Skip to main content

Full text of "Inside Atari DOS"

See other formats


,--»'• 



'^/inn n \\ 



Mi \\ \\ \\ 



$19.95 



. , ~.^.^E^i^^^yg«»*^ 



■- ^'„w^^nj..-V>-ti'/^-j5ii 






f w-VSftS- -*-*Vycy>. « 



;«Xfc^'li»*^^<''S»^'***'«*^ 




-iV-^y^ 



: INSIDE ATARI DOS 





<_ 



From The Editor's of COMPUTE! Magazine and 
Optimized Systems Software, inc. 



INSIDE 
ATARI DOS 



Compiled by Bill Wilkinson, 
Optimized Systems Software, Inc. 



Published by COMPUTE! Books, 

A Division of Small System Services, Inc., 
Greensboro, North Carolina 

ATARI is o registered trademark of Atari, Inc. 




Preface 



This book contains the only complete and official listings for the disk 
File Manager System (FMS) commonly known as "Atari DOS 2. OS." 
You will note that we have clearly stated that the purchase of this 
book does not entitle you to make, sell, give, or otherwise distribute 
copies of either the original Atari DOS 2. OS or any modified version 
you may produce as a result of using this book. 

By way of information, should you desire to produce and distribute 
a modified version of this product (e.g., to support a new disk drive), 
you must sign a contract and licensing agreement with the party who 
owns the rights to grant such licenses for non-exclusive uses. Currently, 
Optimized Systems Software is the only entity able to grant such 
licenses. 

Some of you may find it strange that the publishers of COMPUTE! 
mai'azine are publishing this book. You might wonder why Atari, 
Inc. , hasn't released this information before. Why can you only obtain 
distribution rights from Optimized Systems Software? For the answers 
to these and other questions we present the following Introduction, 
an Inistorical perspective on the development of the systems software 
for the Atari Home Computers. 



All reasonable care has been taken in the writing, testing, and correcting of the text and of the 
sottv'are within this book. There is, however, no expressed or implied warranty of any kind fVom 
the authors or pubUshers with respect to the text or software herein contained. In the event of 
any damages resulting from the use of the text or the software in this book, the authors or 
publishers shall be m no sense liable. Please review the important cautions noted in Appendix A 
regarding the use of this book. 

Copvright © 1982 text. Small System Services, Inc. 

Copyright © 1978, 1979, 1980, 1982 program listings. Optimized Systems Software, Inc. 
AH rights reserved. Reproduction or translation of any part of this work beyond that permitted 
by sections 1 07 and 1 08 of the United States Copyright Act without the permission of the ' 
copyright owner is unlawful. 

Printed in the United States of America 

ISBM 0-942386-02-7 

10 98765432 



Table of Contents 



Preface Page ii 

Introduction; Being a History of Two Births: "Coleen" and "Candy" Page iv 

Chapter One: Atari DOS Overview Page 1 

Chapter Two: Disk Organization Page 10 

Chapter Three: FMS File Control Blocks (FOB) Page 15 

Chapter Four: FMS Initialization Page 17 

Chapter Five: FMS Entry Page 22 

Chapter Six: FMS Exit Page 23 

Chapter Seven: Device Dependent Commands Page 25 

Chapter Eight: FMS Open Routines Page 3 1 

Chapter Nine: FMS Close Routines Page 34 

Chapter Ten: The GET BYTE Routine Page 36 

Chapter Eleven: The PUT BYTE Routine Page 37 

Chapter Tweh^e: Burst I/O Page 38 

Chapter Thirteen: Reading the Directory as a File Page 40 

Chapter Fourteen: Sector I/O Routines Page 42 

Chapter Fifteen: File Name Decode Routine Page 46 

Chapter Sixteen: Directory Searching Page 48 

Chapter Seventeen: Write Next Sector Page 50 

Chapter Eighteen: Read Next Sector Page 51 

Chapter Nineteen: Get and Free Sector Routines Page 53 

Chapter Twenty: The Boot Process Page 55 

Chapter Twenty-One: Maintaining the Boot Record Page 57 

Atari DOS 2. OS Page 59 

Appendix A: An Intermediate User's Guide To This Book .... Page 102 



COMPUTE! Books is a division of Small System Services, Inc., 

Puhlisliers of COMPUTE! Magazine 

Editorial Offices are located at: 

625 Fulton Street, Greensboro, NC 27403 USA. (919)275-9809 

Optimized Systems Software, Inc. , is located at: 

10379 Lansdale Avenue, Cupertino, CA 95014 USA. (408)446-3099. 



Introduction 

BEING A 
HISTORY OF 
TWO BIRTHS 

"COLEEN" 

AND 
"CANDY" 



I don't know exactly when the concept of the Atari Computer was 
developed within the corporate mind of Atari, Inc., nor do I know all 
of the people responsible for nursing that concept into reality. The 
following history covers the relationship with Atari, Inc., during the 
evolution of the system software. 

Sometime in early 1978, when the Atari 800 and 400 were still 
called "Coleen" and "Candy" and were still in the breadboard stages. 
Atari bought a copy of the source for Microsoft 8K BASIC. This 
version of BASIC was fundamentally the same product that was 
implemented by Commodore in the early PETs, was used by OSI, and 
was a close ancestor of Applesoft. Six months and many, many Atari 
man-hours later, that 8K BASIC was almost functioning properly on 
the Atari prototypes. But buying source for a program buys you just 
that: source. Generally, you also receive little documentation, 
sometimes obscure code, no guide to modification, and no real support. 
What to do? The products were due to be shown in early January, 
1979, at the Consumer Electronics Show (CES) in Las Vegas, 
Nevada. 

Enter Shepardson Microsystems, Inc. (SMI), my employer at 
that time. Though little known by the microcomputer pukic, SMI 
had already produced some very successful, private labeled 
microcomputer software. Among our better-known efforts were the 
original Apple DOS, Cromemco 16K Extended BASIC, and 



Cromemco 32K Structured BASIC (just being completed at that 
time). Also, we had done some work for Atari on a custom game 
processor. (Which used a 12-bit ROM and 5-bit RAM configuration 
and was well received at Atari, but never produced.) 

Coincidentally, about that same time SMI had also purchased 
source for Microsoft 6502 BASIC. After producing Apple's DOS, we 
had the bright idea of mating the Apple II peripheral bus with the 
KIM/SYM/AIM system bus (and it still seems like a good idea to us, 
but ...). The idea was to provide a disk system (Apple's) to the Single 
Board Computer market. Needing a BASIC to sell with the system, 
we plunked down a few grand and purchased Microsoft's. Though it 
looked to us like it would be difficult to modify, we were intending to 
resell it with a minimum of changes, so it seemed appropriate. 

A New BASIC? 

Re-enter Atari, some time in the late summer of 1978, asking if SMI 
could help them. With Microsoft BASIC? Well ... we really didn't 
want to, but ... Could we propose a new BASIC? We talked. And 
had meetings, and a study contract, and more meetings, and finally 
we wrote a specification for a lOK, ROM-based BASIC. (I still have a 
copy of that spec, and it's amazing how little the final version deviated 
from that original.) 

Of course, in the middle of all these discussions, Atari naturally 
divulged how their (truly superb) ROM-based Operating System 
would interface both with BASIC and with various devices. 
Somewhere in here, my memory of the sequence of events and 
discussions becomes a little unclear, but suffice it to say that we found 
ourselves making a bid on producing not only a BASIC for Atari, but 
also the File Manager (disk device driver) which would change Atari 
OS to Atari DOS. 

Sometime in late September, 1978, the final proposal was made 
to Atari, and it was accepted by them shortly thereafter. In mid- 
October, 1978, we received the go-ahead. The project leader was Paul 
Laughton, author of Apple DOS. The bulk of the work ended up 
being done by Paul and Kathleen O'Brien. Though I was still involved 
in the finishing touches on Cromemco BAcSIC, I take credit for 
designing the floating point scheme used in Atari BASIC. Paul Krasno 
implemented the math library routines following guidelines supplied 
to us by Fred Ruckdeschel (author of the acclaimed text, BASIC 
Scientific Subroutines). And, of course, much credit must go to Mike 
Peters, our combination keypuncher/computer operator/junior 
programmer/troubleshooter. 



Since we obviously couldn't have the Atari machines to work on 
(they hadn't been built yet), the first step was to bring up an emulator 
for Atari's CIO ("Central Input-Output," the true heart of Atari's 
OS) on our Apple II systems. With Paul Laughton leading the way 
(and doing a lion's share of the work), the pieces fell together quickly. 
"Little" things had to be overcome: the cross-assembler was modified 
to handle the syntax table pseudo-ops, the 256-byte Apple disk sectors 
had to be made to look like 128-byte Atari sectors, the BASIC 
interpreter seemed to function, but was waiting for the floating point 
routines. And there are funny things to tell of, also. Like our cross- 
assembler, running on an IMP-16P (a 1973 vintage, 16-bit, bit-sliced 
PMOS microprocessor) that used keypunched cards for input, a floppy 
disk (with no DOS) as temporary storage, and a paper tape punch as 
output. 

Somehow, Kathleen and Paul guided the two programs unerringly 
toward completion. On December 28, 1978, Atari's purchasing 
dej^artment at last delivered a signed copy of the final purchase order. 
It called for delivery of both products by April 6, 1979. There was a 
clause which provided for a $1,000 per week incentive (if we finished 
early) and penalty (if we finished late). What is especially humorous 
about that December 28th date is that the first working versions of 
both BASIC and FMS had already been delivered to Atari over a week 
before! That is fast work. 

Fortunately, then. Atari took their new Atari BASIC to CES. 
Unfortunately, there was a limit on the amount of incentive money 
collectible. Oh, well. 

In the months that followed, SMI fixed bugs, proofread manuals, 
and worked on other projects (including the Atari Assembler/Editor, 
which was mostly Kathleen's effort). The nastiest bugs in BASIC were 
fixed by December, 1979, but it was too late: Atari had already 
ordered tens of thousands of BASIC ROMs. The FMS bugs were 
easier to get fixed, since DOS is distributed on disk. 

In mid- 1980, Paul Laughton once again tore into FMS. This 
tiir.e, he modified it to handle the ill-fated 815 double-density disk 
drive and added "burst I/O" (and there will be much more about both 
these subjects in the technical discussion that follows). 

In late 1980, and early 1981, Bob Shepardson, owner of 
Shepardson Microsystems, Inc. , decided that the pain and trouble of 
having employees wasn't justified by the amount of extra income (if 
any) that he derived. Though we still occasionally function in a loose, 
cooperative arrangement, the halcyon days of SMI seem to be over. 



A New Beginning 

I negotiated with Bob Shepardson for his rights to the Atari products 
(FMS, BASIC, and the Assembler/Editor) and their Apple II 
counterparts. Thankfully, Atari had purchased from SMI only a non- 
exclusive right to distribute these products. SMI had retained the 
rights to license other users on a similar non-exclusive basis (and, 
indeed, SMI sold a version for the Apple II during most of 1980). 

So now it was frantic time again: this was February 25, 1981, and 
the West Coast Computer Faire was April 3rd. But our brand new 
company. Optimized Systems Software, arrived on time, bringing 
with it BASIC A+ , OS/A+ and EASMD. All three were enhanced, 
disk-based versions of the original Atari programs (and, in fact, derived 
some of their enhancements from the previous OSS Apple II 
products) . 

The products have been well received by the Atari user 
community, in part due to the fact that they are truly compatible, yet 
enhanced, versions of standard Atari software. 

Wily This Booic? 

The decision to publish these listings was not an easy one to make; 
and it is, in its own way, an historic occasion. After all, have you ever 
seen anyone offering source or listings of CP/M, the most popular of 
all computer operating systems? Since Atari, to their credit, has 
hcinored the original agreement with SMI and not released either 
source or listings without permission, the responsibility for doing so 
seemed to rest with OSS. 

But Atari has set a powerful precedent by publishing the listings 
of DUP (their portion of DOS 2. OS) and the OS ROMs. The clamor 
from Atari users for the source for FMS finally even reached us, so we 
hsve bowed to the inevitable, and honored the same commitment 
that Atari has made: to release as much information and aid as possible 
to the user community. 

We hope that the users will appreciate these efforts and, in turn, 
respect our rights and Copyrights. As long as there is a mutual respect 
and benefit, you, the user, can expect continued support. 

AI>out Ihis Booic 

^X'ith the release of this book, the dedicated Atari enthusiast can 
e>:amine all the inner workings of Atari DOS and modify his (or her) 
system to his heart's delight. Rather than simply publish listings, we 
have chosen also to provide a complete guide to the workings of FMS. 
Although the listing itself is relatively clear and commented, all 



but the most expert would have trouble plowing through some of the 
toniuous logic necessary in such a program. The guide included here 
describes all aspects of the FMS, including the external view, the 
chsitts and tables, the various interfaces, and (in copious detail) the 
functions of the individual subroutines (including complete entry and 
exit parameters). 

There is much of value here even for the person who never 
intends to modify Atari DOS. We feel that FMS is a fairly well- 
structured, relatively sophisticated, system level assembly language 
program. We hope that most users will gain by the insights presented 
here. 

We would welcome any notes you would care to send pointing 
out errors either in the DOS or in this book. 

Bill Wilkinson 
Optimized Systems Software 
Cupertino, California 
February, 1982 



Chapter One 

ATARI 
OVERVIEW 



The standard Atari Disk Operating System, DOS 2.08, consists of 
four separate elements, ranked as follows in order of their "visibility" 
to the average DOS user. 

1. DUP - Disk Utility Package 

2. CIO - Central Input/Output 

3. FMS — File Management System 

4. SIO - Serial Input/Output 

It is helpful to understand the entire Input/Output (I/O) process. 
While this book is intended to give detailed information on the 
workings of FMS, this overview will attempt to at least show how the 
four elements of DOS are connected. To this end, we would first call 
your attention to Figure 1. This figure is, itself, an overview of the 
entire Atari I/O system, including indications as to how and where 
data and control flows between the various elements thereof. Figures 
1-1 through 1-4 show "close-ups" of portions of this diagram as they 
re .ate to the four elements of EXDS. 

In these figures, the rectangular boxes represent system elements, 
and are appropriately labeled. The wide, lettered arrows represent the 
flow of data (via buffers, control blocks, or even registers) between 
the various elements. The narrow, numbered arrows show how and 
where control, and control information, is transferred. 

1-1. Disk Utility Pacicage 

DUP (which shows as "DUP. SYS" in a disk directory listing) is the 
most obvious and visible element of Atari EXDS. DUP's function is to 
provide the user with keyboard access to the various file management 
functions in FMS. It does so via the menu which is displayed when, 
for example, the user keys "DOS" from BASIC. Actually, the menu 
offers several options which are not directly a part of the FMS (e.g. , 
copy and duplicate files). Refer to the Atari Disk Operating System U 



CHAPTER ONE 



Reference Manual (part number C016347) for more information. 

DUP is not an integral part of FMS. DUP may be relatively easily 
replaced with a program of the user's choice. In fact, our own OS/A + 
does exactly that: instead of a menu, the user is given a command- 
driven keyboard interface to the other elements of DOS. 

DUP is not even a privileged portion of IX)S (excepting, perhaps, 
for reeding to know a little of the internals of FMS when it performs a 
Duplicate Disk function). Any user application program (and that 
includes Atari BASIC, BASIC A + , EASMD, and many, many 
more) interacts the same way DUP does. Figure 1-1 shows the "proper" 
flow of control in EXDS. Note that DUP transfers control only to 
CIO, which, in turn, transfers control to FMS and thence to SIO. An 
application program which maintains this protocol should be able to 
perform correctly in any Atari system, regardless of the revision of the 
OS ROMs and/or FMS. 

Of course, control is not the only thing which DUP must transfer. 
It must also tell CIO where its data is and what to do with it. Refer to 
Figure 1-2 for a diagram of the complete application/CIO interface 
(again, it is labeled in this way because DUP is just another application 
program as far as the rest of DOS is concerned). CIO always expects 
an Input/Output Control Block (lOCB) and usually (i.e., for all but 
the simplest operations) needs a buffer into or out of which it may 
perform its operations. 

1-2. Central Input/Output 

CIO is actually the heart of the entire Atari Computer. It is less than 
800 bytes long and yet serves to handle virtually all the input and 
output which takes place in the computer. CIO is a part of the Atari 
"OS ROMs," the I OK byte package which also houses the floating 
point routines, the default character set, the interrupt handlers, and 
several device drivers. 

The entire set of operations summarized in Figure 1-2 is covered 
in detail in the Atari OS Manual (C01655) and will be covered only 
briefly here. Readers of COMPUTE! will also find some helpful material 
on this subject in issues #18 through #21 (November, 1981, through 
February, 1982) in the "INSIGHT: ATARI" columns. 

In order to allow easy control and data flow, CIO is written to 
expect and provide for eight Input/Output Control Blocks (lOCBs) 
which are used to pass the information needed to process the various 
kinds of I/O requests. An application places the necessary command 
and control information in an lOCB which it selects (data path A). If 
a buffer is required, the application must provide one (data path C) 



CHAPTER ONE 



and place its address into the lOCB. When ready to execute the I/O 
command, the appUcation places the lOCB number (times 16) in the 
6502's X-register (data path C) and executes a JSR call to CIO (control 
path 1 ). Note that a few command variations may pass data via the 
6502's A-register, but we may consider that simply a special case 
location of the user's buffer. 

When CIO receives control, it examines the information in the 
lOCB (and, for some operations, in the user buffer) to determine 
what actions it is to perform. Generally, this action requires the 
execution of a device handler routine. 

A device handler (interchangeably known as a device driver) is a 
system routine that performs I/O operations for a specific device (or 
class of devices). Examples of device handlers include the "P:" driver 
(the printer) and the "E:" driver (the screen/keyboard editor). Figure 
1-3 illustrates the interface between CIO and the various device 
handlers. Note that FMS is simply another device handler as far as 
CIO is concerned, having been given the name "D:". 

All device drivers are required to contain a table of address pointers 
(known as the Device Vector Table) to various specific routines 
within themselves, including a device OPEN routine, GET 
CHARACTER routine, etc. The name of a device and the address of 
this table is placed in CIO's Device Handler Table. When an 
application program makes an I/O request to CIO for a specific device, 
CIO searches the Device Handler Table for the given name and 
corresponding Device Vector Table address. With the thus-located 
vector table, CIO can then call the appropriate device handler routine 
(via a JSR, along control path two of Figure 1-3). 

1-3. File Management System 

As. stated above, FMS is actually simply another device driver as far as 
CIO is concerned. The control and data flows shown in Figure 1-3 are 
equally valid for all device drivers in the Atari system. Note that 
many of the drivers in the default ("as-shipped") system reside entirely 
within the so-called OS ROMs. Although it resides in RAM, what is 
somewhat unique about FMS is that the Atari system initialization 
code contains a segment of "boot" code which loads FMS into memory 
upon power-on. 

FMS is the system device handler for all I/O operations that 
specify the device name "D" (including "Dl:", "D2:", etc.). In order 
to perform its functions, FMS examines the data in the specified 
ICCB (data path F). It may also examine, read, or write data to or 
frcim the user-supplied buffer (data path I). Data path H is used to pass 



CHAPTER ONE 



the I(ZXZ!B-designator (again, via the X-register) and single-byte transfer 
data (via the A-register). 

FMS is called upon to perform a variety of tasks, including all 
disk I/O, file renaming, protecting, deleting, etc. Since the rest of 
this book consists of a listing of FMS along with detailed explanations 
of all sections thereof, we will not now dwell on the inner workings of 
FMS. 

However, we do need to note that, in order to perform its work, 
FMS must transfer data to and from the disk. FMS accesses the disk 
drive via SIO, the fourth element of DOS. 



1-4. Serial Input/Output 

SIO is the name given to the component of DOS which drives and 
controls the Atari serial I/O bus and the various peripherals (disk, 
printer, modem, etc.) which are placed on that bus. Figure 1-4 
illustrates the interface between FMS and SIO, but it could just as 
well serve to show (for example) how the printer driver talks to the 
various Atari printers. 

The SIO is primarily driven by a request placed in SIO's Device 
Control Block (DCB) by the device handler (data path K) followed 
by a transfer of control (control path three) via a JSR. SIO uses the 
information in the DCB (data path M) to determine what it needs to 
do. If the EXHB specifies a serial bus data transfer (as opposed to, for 
example, a status request), then the address of the data buffer must 
also be passed (via a field in the DCB). For example, the FMS buffer 
shown is accessed via data paths J (from FMS) and L (from SIO). 

Although SIO only understands the single system DCB, the 
buffer specified may be located anywhere in memory. FMS takes 
advantage of this to implement "burst I/O" (discussed in section 12), 
which has SIO transferring data directly to or from the user's buffer 
(data path E). 

Since the actual disk data transfer occurs in fact within the 810 
disk drive and, since SIO communicates to the drive via data path N, 
one might reasonably argue that the disk drive constitutes a fifth 
component of DOS. However, because the disk drive functions are 
preprogrammed in ROM, and because SIO implements the only 
method of accessing the disk (as well as most other peripherals), then, 
for all practical purposes, even machine language software may treat 
SIO as the last link in the I/O chain on the Atari Computers. 

Once again, we remind you to study Figure 1. In the following 
dissertation and dissection of FMS, we shall refer to this chart often. 



o 



-1 

■p o 

So 

O) o 
Q 

o 



1^ 1^ 
.y DJOCL 

< 



Q 



ox 




X 




o 



1(3 

CO 

o 




CO 



CO 




0) 

o 

D 
0) 



2 5 

iz _0 
D 



< 



SJ OiOol 
112 I R 



^ to > 



3 
Q. 

O 



5 



0^:C>[ 



CO 



A 



CD 3 LI. U_ LXJ Oi 



<X> 



CO 



ft 



> 




QOco 



□3 3 i-L u_ Lu C^ 




A 



coco 



A 



>[ 



■OUCD 



< 



(D 
O 
O 
1= 

i^- 

CO ii 
- ij 

O £1 

^-^^ 

"- CD 
(J 
> 
(D 

I 

C) 
C) 



CD Z) U_ U_ LU Ci^ 



D g ^^ 
.y o) ocl 

< 



o> 



<=> 





QUm 



A 



-OUcQ 



<I 



^ « > 

cob^ 



CD 
O 
D 

|o 

u.: CO 

CO 



3 

a 

-*— 

3 

o 

c 
D 
O 



<:^=> 



QOoD 




A 



> 



o 2 _ 
.y a>o a; 

< 



<x> 



CD Z3 Ll_ u_ LU D; 



<:> 



<Z> 




cU 






>[ 



• oum 



<0 






A 



Chapter Two 

DISK 
ORGANIZATION 

The purpose of FMS is to organize the 720 data sectors available on an 
810 (diskette into a system of named data files. FMS has three primary 
data structures that it uses to organize the disk: the Volume Table of 
Contents, the Directory, and Data Sectors. The Volume Table of 
Concents is a single disk sector which keeps track of which disk sectors 
are available for use in data files. The Directory consists of directory 
sectors. It is used to associate file names with the location of the files' 
sectors on the disk. Each Directory entry contains a file name, a 
pointer to the first data sector in the file, and some miscellaneous 
information. The Data sectors contain the actual data and some 
control information that link one data sector to the next data sector 
in the file. Figure 2-1 illustrates the relation between the Directory 
and the Data files. 

Disk Directory 

The Directory starts at disk sector $169 and continues for eight 
contiguous sectors, ending with sector $170. These sectors were 
chos(m for the directory because they are in the center of the disk and 
therefore have the minimum average seek time from any place else on 
the disk. Each directory sector has space for eight file entries. Thus, it 
is possible to have up to 64 files on one disk. 

A Directory entry is 16 bytes in size, as illustrated by Figure 2-2. 
The directory entry flag field gives specific status information about 
the current entry. The directory count field is used to store the number 
of sectors currently used by the file. The last eleven bytes of the entry 
are the actual file name. The primary name is left justified in the 
primary name field. The name extension is left justified in the extension 
field. Unused filename characters are blanks ($20). The Start Sector 
Number field points to the first sector of the data file. 

Data Sectors 

A Data Sector is used to contain the file's data bytes. Each 128 byte 
data sector is organized to hold 125 bytes of data and three bytes of 



10 



CHAPTER TWO 



control information as shown in Figure 2-3. The data bytes start with 
the first byte (byte 0) in the sector and run contiguously up to, and 
including, byte 124. The control information starts at byte 125. 

The sector byte count is contained in byte 125. This value is the 
actual number of data bytes in this particular sector. The value may 
range from zero (no data) to 125 (a full sector). Any data sector in a 
file may be a short sector (contain less than 125 data bytes). 

The left six bits of byte 126 contain the file number of the file. 
This number corresponds to the location of the file's entry in the 
Directory. Directory entry zero in Directory sector $169 has the file 
number of zero. Entry one in Directory sector $169 has the file number 
one — and so forth. The file number value may range from zero to 63 
($3F). The file number is used to insure that the sectors of one file do 
not get mixed up with the sectors of another file. 

The right two bits of byte 126 (and all eight bits of byte 127) are 
used to point to the next data sector in the file. The ten bit number 
contains the actual disk sector number of the next sector. Its value 
ranges from zero to 719 ($2CF). If the value is zero, then there are no 
more sectors in the file sector chain. The last sector in the file sector 
chain is the End-Of-File sector. The End-Of-File sector may or may 
not contain data, depending upon the value of the sector byte count 
field. 

Volume Table Of Contents (VTOC) 

The VTOC sector is used to keep track of which disk sectors are 
available for data file usage. The VTOC sector is located at sector 
$16'8. Figure 2-4 illustrates the organization of the VTOC sector. The 
most important part of the VTOC is the sector bit map. 

The sector bit map is a contiguous string of 90 bytes, each of 
which contains eight bits. There are a total of 720 (90 x 8) bits in the 
bit map - one for each possible sector on an 810 diskette. The 90 
bytes of bit map start at VTOC byte ten ($0A). The leftmost bit ($80 
bit) of byte $0A represents sector zero. The bit just to the right of the 
leftmost bit ($40 bit) represents sector one. The rightmost bit (bit 
$01 ) of byte $63 represents sector 719. 

The fact that EMS interprets the bit map as representing sectors 
zero through 719 is a bug. The Atari 810 disk drive will not accept 
commands for sector zero. It will accept commands for sector 720. In 
other words, the bit map is skewed by one. The problem cannot be 
fix€:d now because there are already tens of thousands of diskettes 
whose bit maps are to be interpreted as representing sectors zero through 
719, and because some savvy applications writers have taken advantage 



11 



CFUVPTER TWO 



of this feature. (A bug which generates useful side effects is known in 
the programming profession as a feature. ) Sector 720 can never be 
use(i by FMS and is therefore available for miscellaneous purposes. 



Directory Sectors 
Sector $169 - 




Figure 2-1 



12 



CHAPTER TWO 



Typical Directory Sector 



Er^tryO 


Entry! 


Entry 2 


Entry 3 


Entry 4 


Entry 5 


Entry 6 


Entry? 



Typical Directory Entry 



1 



13 



Count 



SSN 



Primary Nome 



Extension 



Start Sector Number (Low, Higti) 
The Sector Number of ttie First 
Sector in the File Sector Chain 



Count (Low, High) 
The Number of Sectors in the File 



Flag 
$00 - Entry Has Never Been Used 
$80 - Entry Has Been Deleted 
$40 - Entry In Use 
$20 - Entry Locked 
$02 - File Created By DOS 2 
$01 - File Opened For Output 



Figure 2-2 



13 



CHAPTER TWO 



Typical Data Sector 



Data 
125 Bytes 



Control 



Byt€i 125 
Byt6i 126 

Byt€i 127 



1 \-^ 




j 


■r 








V ^ 






1 • k-^ 



Number Bytes Used In Sector (0-125) 
Next Sector Number (Might Two Bits] 
File Number (0-63) 
Next Sector Number (Low Eight Bits) 



Figur€J 2-3 
VrOC Sector ($168) 



0-9 
Misc. info. 



$0A-$63 

Sector Usage 
Bit Map 



$64-$7F 
Unused 




1 
3 
5 
6 

















1 1 1 



Type Code ( = in DOS 2.0) 
Number Sectors Total ($2C3) 
Number Unused Sectors 
Reserved 
Unused 



- Eacti bit represents a specific sector 

- Thie left most bit ($80) of byte $0A is sector number (does not exist) 

- Thie next bit ($40) of byte $0A is sector number 1 

- The right most bit ($01) of byte $63 is sector number $719. 

- If the bit is one, the sector is unused and available 

- If the bit is off (zero), the sector is used 

Figure 2-4 



14 



Chapter Three 

FMS 

FILE CONTROL 

BLOCKS 

(FOB) 



The FMS File Control Blocks are used to store information about files 
that are currently being processed. Each file that is being processed 
concurrently by FMS requires one FCB. Since the Atari system has 
eight lOCB's, FMS must be prepared to handle up to eight files 
concurrently, thus there are eight FCBs. The FCBs were designed to 
have a one-to-one correspondence with the lOCBs. When a file is to 
be processed with ICXI^B number three, FMS will use FCB number 
three for that file. When a file is to be processed with lOCB number 
five, FMS will use FCB number five for that file. Each FCB is the 
same size as an lOCB (16 bytes). The FCBs are located in a contiguous 
RjKM area just like the lOCBs. When CIO calls FMS, the X register 
contains the displacement (ICXDB number times 16) to the lOCB 
making the request. The FMS uses this displacement value to access 
both the lOCB information and the FCB information. Please refer to 
the listing at location $1381 for the following discussion about the 

fc:bs. 

FCBFNO 

The file number of the file currently being processed. The value (zero 
to 63) is shifted left two bits. When a file has been opened for reading, 
this value will be used to check for a file number mismatch in the data 
se<:tors. When a file is opened for write, this value will be placed in 
the file number field of the data sectors. 

FCBOTC 

0]3en Type Code. This value is used as a flag to indicate which mode 
the file has been opened for: 

Input is $04. 

15 



CHAPTER THREE 



Output is $08. 
Update is $0C. 
Append is $01. 
Directory read is $02. 

FCBSLT 

This is a tlag used to indicate that the file being processed was created 
by EOS 1 rather than OOS 2. The Data Sector length byte has a 
different interpretation under DOS 1 . 

FCBFLG 

This field is a working flag. If the value is $80, then the file is eligible 
to ac:quire new data sectors. Files that are opened for Output or Append 
are e'ligible to acquire new data sectors. If the value is $40, then the 
sector currently is in a memory buffer, has been modified, and needs 
to b<; written back to the disk. 

FC»MNL 

If the file is opened for Output or Append, this value will be either 
125 or 253 depending upon the drive type. The 253 value is meant for 
the i\tari 815 dual density drive. If the file is opened for Read or 
Update, then this value represents the number of data bytes that are 
in the data sector currently in a buffer. This value is obtained from the 
Data Sector data length field (byte 125 of the data sector.) 

FCBDLN 

This value points to the next data byte to be operated on in a data 
sector. If the file is opened for Output or Append, this value points to 
the next available (unused) data byte in the current data sector. If the 
file is opened for Update, then this value points to the next data 
sector byte to be either read or modified. If the file is opened for 
Inptit, then this value points to the next byte to be read. 

FCBBUF 

This value is an index into the sector buffer table. The sector buffer 
table is a list of buffer addresses. When a file is being processed, a 
sector buffer is required to hold data sectors. This field tells FMS 
which FMS buffer has been allocated to the file. 

FCBCSN 

The sector number of the sector currently in the buffer is stored in this 
field. 

16 



FCBLSN 

The sector number of the next sector in the file chain is stored in this 
field. 

FCBSSN 

If the file has been Opened for Append, then this field contains the 
sector number of the start of the sectors to be appended to the file 
when the append file is closed. 



Chapter Four 

FMS 
INITIALIZATION 



DUP gets control whenever the system is booted or the RESET key is 
pressed. DUP will call the FMS initialization routine, DINIT at $7E0. 

DINIT 

Functions: 

1) Determine how many (and what type of) disk drives will be 
used. 

2) Set up a drive table and allocate a drive buffer for each drive. 

3) Allocate sector buffers and build the sector buffer table. 

4) Clear the FCBs to zero. 

5) Set MEMLO. 

6) Enter the D: device into the Device Handler Table. 

7) Exit to caller via RTS. 

Drive Determination 

Th<; DRVBYT byte at $70A is used to tell FMS how many disk drives 
will be used and what the drive number of the drives will be. The 



17 



CHAPTER FOUR 



rightmost bit (bit $01) indicates drive 1. The next left bit ($02) 
indicated drive 2 - and so forth. If the bit is one, then the drive is to 
be used. If the drive is zero then the drive is not to be used. The code 
will allocate up the eight drives, even though the 810 hardware only 
has switches for drives 1,2,3 and 4. 

If DRVBYT indicates that a drive is to be used, then FMS issues 
a status command to that drive to determine if it is active and what 
type (810 or 815) of drive it is. 

Drive Allocations 

The drive determination process sets up two tables (Figure 4-1). The 
first table is the DRVTBL. This table is indexed into by the drive 
number (minus one). If the value in the table is zero then the drive is 
not to be used. If the value is one, then the drive is an active 810 and 
requires one drive buffer. If the value is two, then the drive is an 815 
and requires two 128 byte buffers. 

The second table is the drive buffer table. The drive buffer table 
contains the address of the drive buffer to be used for each drive. This 
Drive Buffer will be used to hold the VTOC sector on the diskette in 
the drive. The table is separated into two sections: DBUFAL contains 
the least significant address byte and DBUFAH which contains the 
most significant address byte. The drive buffer table is also accessed by 
the drive number (minus one). 

When a file is being processed, the Drive number is obtained 
froiTi the lOCB Device Number field, ICDNO. The obtained value is 
decxemented by one and is then used as an index into the Drive Tables. 
The Drive Type is copied from the DRVTBL entry to DRVTYP 
($1 2FE) for easy access by FMS. The Drive Buffer address is copied 
from the DBUFAL and DBUFAH table entries to the zero page drive 
buffer pointer, ZDRVA ($45). 

Sector Buffer Allocations 

The SABYTE at location $709 is used to inform FMS about the 
number of 128 areas to be allocated as sector buffers. One 128 buffer is 
required for each file which is to be processed concurrently on 810 
drives. Two 128 byte buffers are required for each file which is to be 
processed concurrently on 815 drives. 

The Sector Buffer Allocation table, SECTBL at $1319, is used to 
indicate if a buffer is available for allocation to a file (Figure 4-2). If a 
buffer is available, the entry is set to zero. If the buffer is not available, 
the entry is a minus value. The table is 16 bytes in size and therefore 
cari be used to allocate up to sixteen 128 byte buffers. During the 

18 



CHAPTER FOUR 



initialization process, entries which are to be unused are set to a minus 
value. 

The Sector Buffer Address Table is a table of addresses which 
point to the individual sector buffers. The table is divided into two 
parts: SABUFL contains the least significant address byte, SABUFH 
contains the most significant address byte. 

When a file is being processed, an available buffer number is 
found in SECTBL by search for a zero valued entry. The located 
buffer is allocated to the file by entering a minus value ($80) into the 
table and placing the corresponding buffer number into the DCB 
buffer number field, FCBBUF. When the file processing is done, the 
buffer is deallocated by setting the SECTBL entry to zero. 

Setting MEMLO 

The Atari MEMLO location ($2E7) is set after the FMS buffers have 
be4;n allocated. The address of the last sector buffer allocated is 
incremented by 128. This value is then placed into MEMLO. 

Dcivice Handler Table Entry 

The Device Handler Table ($31 A) is searched for a "D" entry or the 
first (from the top) empty entry. When an appropriate entry is found, 
FVIS inserts (or reenters) "D" as a DEVICE NAME and sets the 
DEVICE vector entry to point to the FMS Device Vector table at 
DFMSDH ($7CB). 



19 



CHAPTER FOUR 



$70A DRVBYT .BYTE $0F ; Allocates Drive 1,2,3,4 

i 



Drive Bits 







r 



1111 



S1311 DRVTBL 



• + 9 



Drive Table 



3 



Drive No. 


Index 


1 





2 


1 


-••3 


2 


4 


3 


5 


4 


6 


5 


7 


6 


8 


7 






1 





1 





2 





2 



























Drive Type From Status 

810 Drive -m 

810 Drive •« 

815 Drive -• 

815 Drive ■• 

No Drive 
No Drive 
No Drive 
No Drive 



[1;1329 DBUFAL 



• + 8 : Drive Butter Address Table (Lov>/) | 



Oi 



1331 DBUFAH 



• + 8 : Drive Butter Address Table (High) 



Q: 



70C SASA 



.WORD 



$1A7C : Butter Start Address 



Dr ive No. 
1 
2 
-••3 
4 
5 
6 
7 



Index 
~0~ 

1 

2 

3 

4 

5 

6 

7 



DBUFAH 



DBUFAL 



1A 
1A 


a 




7C 
FC 




IB 




7C 


1C 




7C 


00 




00 


00 




00 


00 




00 


00 






00 



128 Byte Butter For Drive 1 At S1A7C 
256 Byte Butter For Drive 3 At $1B7C 



Figure 4-1 

Drive Tables 



20 



CHAPTER FOUR 



$1319 SECTBL 


• + 16 ; Sector Allocation Table 


Buffer Number 







00 


Buffer Is Available 


1 


00 




2 


00 




3 


00 






00 
00 




5 




6 


00 


Buffer Is Available 


7 


FF 


Buffer NOT Available 


8 


FE 




9 


FD 




10 


FC 




11 


FB 




12 


FA 




13 


F9 




14 


F8 




15 


F7 




16 


F6 


Buffer NOT Available 


!;709 SABYTE BYTE 


7 : Number Of 128 Byte Sector Buffers 




S1339 SABUFL 


• + 16 ; Sector Buffer Address (Low) Table 




!)1349 SABUFH 


• + 16 ; Sector Buffer Address (High) Table 


(Last Drive Buffer Address + Dri\ 


/e Type (1 or 2) • 128) 




^ 


Buffer Number SABUFL SABUFH 





1C 




8C 


•• ■' 


1 


1D 




OC 


(Previous Entry + 128) 


2 


ID 




8C 




3 


IE 
1E 




OC 
80 


Sector Buffer 4 Address = $1E80 






5 


IF 




OC 




6 


IF 




80 




7 


20 




OC 




8 


GO 




00 




9 


00 




00 




10 


00 




00 




11 


00 




00 




12 


00 




00 




13 


00 




00 




14 


00 




00 




15 


00 




00 





Figure 4-2 

Sector Allocation Tables 



21 



Chapter Five 

FMS 
ENTRY 



The Device Vector Table for FMS is located at DFMSDH ($7CB). 
The address of this table is placed in the Device Handler Table by the 
FMS Initialization routine. When CIO needs to call an FMS function 
(Figure 1, control path 2), it will locate the address of the function via 
the' table at DFMSDH. This table is the standard Atari Device Handler 
Vector Table. The six entries are for: 

Open 

Close 

Get Byte 

Put Byte 

Status 

Device Dependent (XIO) Commands 

Each of the six FMS entry points starts with a subroutine call to 
the FMS SETUP routine. SETUP ($1164) prepares FMS parameters 
to deal with the particular task to be performed. 

SErup 

Address -$1164 

Entry Registers - A = Possible 'Put Data' data byte. 
X = lOCB number times 16. 

Y = Don't Care. 
Exit Registers - A = Unknown. 

X = lOCB number times 16. 

Y = Sector Buffer Index. 

Functions: 

1) Initialize ERRNO to $9F. This value will be used in the FMS 
exit routines to form a FMS error number in the event of error. 

2) Save the X Register in CURFCB. This value will be used as 
an index to the proper lOCB and the proper FCB for the current 
operation. 

3) Save the value of the stack register as it was upon entry to 

22 



FMS. This value will be used in the FMS exit routine. 

4) Set up drive information values from the drive number 
contained in the zero page lOCB field ICDNOZ. 

5) Allocate a sector buffer to the FCB if one is not already 
allocated. 



Chapter Six 

FMS 
EXIT 



There are two types of FMS exits: the normal exit and the error exits. 
Both of these exit types end up calling the RETURN routine. 

RETURN 

Address -$12D3 

Entry Registers — A = Return Code. 
X = Don't Care. 

Y = Don't Care. 

Exit Registers — A = Possible 'Get Byte' data byte. 
X = lOCB number times 16. 

Y = Return Code. 

Functions: 

1 ) The X register is loaded with the current lOCB number times 
16 from CURFCB. 

2) The return code is placed in the ICXZ^B status field (ICSTA). 

3) The stack register is restored to point to the stack displacement 
at FMS entry from the value saved in ENTSTK. 

4) The possible "Get Data" data byte is loaded into the A 
register. 

5) The Y register is loaded with the return code. 

23 



ClflAPTER SrX 



6) The caller (CIO) is returned to via the RTS instruction. 

eKEATAnd FGREAT 

GP.EAT and FGREAT are the exit points used by FMS when the 
operation has terminated normally. FGREAT is located at $12EA and 
is used to free the sector buffer that has been allocated to the FCB. 
The FRESBUF routine is used to free the buffer. FGREAT exits 
directly to GREAT ($12F0). The GREAT exit point loads the normal 
return code ($01) into the A register and goes to RETURN. 

Error Exits 

The ERREOF exit is called when an end of file condition is found. 
ERREOF loads the end-of-file condition code ($88) in the A register 
and goes to RETURN. 

The ERRIO exit is called if an error occurs during an I/O operation 
(Figure 1, control flow 3). The error code from the DCB (control 
path K) is loaded into the A register as the FMS return code and 
control is passed to RETURN. 

All other errors exits are at the ERxxx labels starting at $12B5. 
Th(; error code is developed by means of a series of 6502 INC 
instructions which increment the ERRNO (which was initialized to 
$9F at FMS entry). The final instruction at the end of the INC chain 
loaiis the final ERRNO value into the A register and control is passed 
directly to RETURN. 



24 



Chapter Seven 

DEVICE 

DEPENDENT 

COMMANDS 



A C'evice Dependent Command is any command which is not Open, 
Close, Get Byte, Put Byte, or Status. When the command value in 
the lOCB is greater than 15 ($0F), CIO will call the Device Handler 
Device Dependent Command routine. The Device Handler must 
det€;rmine if the command is a valid command for that device. The 
Device Dependent Commands that for FMS are: 

Rename 

Delete 

Lock 

Unlock 

Point 

Note 

Format 

The FMS Device Dependent Command routine starts at 
DFMDDC. 

DFMDDC 

Address - $BA7 

Entry Registers - A = Don't Care. 

X = lOCB number times 16. 

Y = Don't Care. 
Exit Registers - A = Unknown. 

X = lOCB and FCB number times 16. 

Y = Unknown. 

Function: 

1) Call SETUP 

2) If the command is Format (254) , then go to the Format routine, 
XFORMAT at $D18. 

3) If the command is not Format, then check that the command 

25 



CHAPTER SEVEN 



value is $20 through $26. If the command value is not in this 
range then exit via the ERDVEXH (Command Error) routine. 
4) If the command is valid, go to the command via the DCDCVT 
vector table. 

XFORMAT 

The XFORMAT routine executes the FORMAT Device Dependent 
Command. 

Address -$D18 

Entry Registers - A = Don't Care. 

X = lOCB and FCB number times 16. 

Y = Don't Care. 
Exit Registers — A = Unknown. 

X = Unknown. 

Y = Unknown. 

Functions: 

1 ) Issue the format I/O command to the drive. This will cause 
the drive to perform the physical formating of the disk. If the 
command returns with good status and there were no bad sectors 
reported, then continue with the logical format operations. In 
the event of physical format errors, exit via the ERDBAD error 
exit. 

2) Clear the drive buffer to zero. 

3) Set the sector count values into the DVDMSN (VTOC 
displacement one) and the DVDNSA (VTOC displacement 
three) fields. 

4) Set all 90 sector bit map bits to one (available). 

5) Deallocate the first four sectors for the boot sectors. 

6) Deallocate the middle nine sectors for the VTOC and the 
Directory. 

7) Write the VTOC to the Disk. 

8) Clear the eight directory sectors to zero. 

9) Exit via the FGREAT exit. 

XDELETE 

The XDELETE routine executes the DELETE Device Dependent 
Command. 

Address — $C3 2 

Entry Registers - A = Don't Care. 

26 



CHAPTER SEVEN 



X = lOCB and FCB number times 16. 

Y = Don't Care. 
Exit Parameters - A = Unknown. 

X = Unknown. 

Y = Unknown. 

Functions: 

1) The filename is decoded via the FNDCODE routine. 

2) The first filename is searched for via the SFDIR routine. 

3) The file, if found, is deleted via the XDELO routine. 

4) If the file just deleted was DOS. SYS then the boot record is 
re-written via the DELEXDS routine. 

5) The directory is searched for the next matching entry. If an 
entry is found then the process repeats at step three. If no further 
matching directory entries are found, then exit via FGREAT. 

XOELO 

Tbe XDELO routine is used to delete the file whose directory entry is 
indicated by the CDIRD (current Directory Displacement) byte 

($1305). 

Address - $C53 

Entry Registers - A = Don't Care. 

X = lOCB and FCB number times 16. 

Y = Don't Care. 
Exit Registers — A = Unknown. 

X = Unknown. 

Y = Unknown. 

Functions: 

1 ) The OPVTOC routine is called to insure that the disk is not 
write protected. 

2) The TSTLCXZIK routine is called to insure that the file is not 
locked. 

3) The file deleted bit is set in the directory entry flag and the 
directory sector is written back to the disk. 

4) The VTOC sector bit map bits for the sectors in the file are 
set to one to make them eligible for reuse. This process is achieved 
by reading each sector in the file sector chain and calling the 
FRESECT routine to change the VTOC bit map. 

5) The VTOC Write Required Bit is set so that the VTOC will 
be written back to the disk. 

27 



CI-IAPTER SEVEN 



XRENAME 

The XRENAME routine executes the RENAME Device Dependent 
Command. 

Address - $BD9 

Entry Registers - A = Don't Care. 

X = ICXDB and FCB number times 16. 

Y = Don't Care. 
Exit Registers — A = Unknown. 

X = Unknown. 

Y = Unknown. 

Functions: 

1) The filename is decoded via the FNDCODE routine. 

2) The directory is searched for the first entry to be renamed. If 
no entry is found then the ERFNF (File not found) exit is taken. 

3) The TSTLOCK routine is called to insure that the file is not 
locked. 

4) If TSTDOS determines that the old filename is DOS. SYS 
then the boot record is rewritten via the DELDOS routine. 

5) If new filename is EXDS.SYS, then the boot record is rewritten 
via the SETDOS routine. 

6) The filename in the directory is changed to the new filename. 

7) The directory sector is rewritten. 

8) The directory is searched for the next filename match. If a 
match is found, then the process repeats at step three. If no 
further match is found then, exit via FGREAT. 



XLOCKAndXUNLOCK 

The XLOCK routine executes the LOCK Device Dependent 
Command. The XUNLOCK routine executes the UNLOCK Device 
Dependent Command. 

Address — $C7C 

Entry Registers - A = Don't Care. 

X = lOCB and FCB number times 16. 

Y = Don't Care. 
Exit Registers — A = Unknown. 

X = Unknown. 

Y = Unknown. 



28 



CHAPTER SEVEN 



Functions: 

1) The XLOCK entry sets the LOCK bit value, DFDLOC ($20), 
into TEMP4. The XUNLOCK entry sets a zero value into TEMP4. 
Both routines then go to XLCOM. 

2) The filename is decoded via the FNIDCODE routine. 

3) The directory is searched for the first file entry match. If no 
match is found, the ERFNF (file not found) exit is taken. 

4) The files directory flag is modified to either LCX3KED or 
UNLCXZlKED by means of the value previously set into TEMP4. 

5) The Directory sector is written back to the disk. 

6) The CSFDIR routine is called to find the next filename match. 
If a match is found, then the process repeats at step four. If no 
match is found, then exit via FGREAT. 

XPOINT 

Th(; XPOINT routine executes the POINT Device Dependent 
Command. 

Address - $CBA 

Entry Registers - A = Don't Care. 

X = lOCB and FCB number times 16. 

Y = Don't Care. 
Exit Registers — A = Unknown. 

X = Unknown. 

Y = Unknown. 

Functions: 

1 ) If the FCBFLG indicates that the file can acquire sectors 
(Opened for Output or Append), then exit via the ERRPOT 
(point error) exit. 

2) If the current sector is not the same as the sector POINTed to 
by the lOCB AUX3 and AUX4 fields, then write the current 
sector back to the disk (if it has been changed). 

3) Read the POINTed to sector into the sector buffer. 

4) Set the FCB next byte pointer, FCBDLN, to the value 
indicated by the user Point data in the lOCB AUX5 field. 

5) Exit to FGREAT. 

XhlOTE 

The XNOTE routine executes the NOTE Device Dependent 
Command. 



29 



CHAPTER SEVEN 



Address - $D03 

Entry Registers - A = Don't Care. 

X = lOCB and FCB number times 16. 

Y = Don't Care. 
Exit Registers - A = Unknown. 

X = Unknown. 

Y = Unknown. 

Functions: 

1 ) The current sector number and data displacement into the 
sector is moved to the appropriate ICXHB fields, ICAUX3, 
ICAUX4, 1CAUX5. 

2) Exit via GREAT. 



30 



Chapter Eight 

FMS 

OPEN 

ROUTINES 



The FMS Open routine, DFMOPN, is called directly by CIO via the 
FMS Device Vector Table, DFMSDH at $7CB. 



DFMOPN 

The DFMOPN routine is the FMS file open routine. 
Address - $8AB 
Entry Registers — A = Don't Care. 

X = lOCB number times 16. 

Y = Don't Care. 
Exit Registers — A = Unknown. 

X = Unknown. 

Y = Unknown. 

Functions: 

1 ) Initialize for this operation by calling SETUP. 

2) Decode the filename via FNDCODE. 

3) Examine the open code in ICAUXl for the open-for-directory- 
read command. If this is a directory read command, go to 
LISTDIR. 

4) If not a directory read, then search the directory for the first 
match on the file name and save the resulting search condition 
on the stack. 

5) Determine the exact type of Open operation to be performed 
by examining the lOCB ACUXl field. If INPUT, go to DFOIN. 
If Output, go to DFOUT. If Update, go to DFOUPD. If Append, 
go to DFOAPN. If none of the above, exit via the ERDVDC 
(device command error) exit. 

31 



CHAPTER EIGHT 



DPOIN 

DFOIN ($8D8) is entered when opening a file for Input. The routine 
pops the stack to determine if the directory search for the file name 
was successful. If the file name was found in the directory, then go to 
DFOUI. If the search was not successful, then exit to ERFNF (file not 
found). 

DI^OUPD 

DFOUPD ($8DD) is entered when opening a file for Update (Input 
and Output). The routine pops the stack to determine if the file name 
was found in the directory. If the file was not found, then exit to 
ERFNF (file not found). If the file was found, insure that the file is 
noi: Locked by calling TSTLOCK. If the file is unlocked, then continue 
at 13FOUI. 

DFOUI 

DFOUI ($8E3) is entered to finish opening a file for Input or Update. 
The read setup routine, DFRDSU, is called. FMS then exits via the 
GREAT exit. 

DFDRDSU 

DFDRDSU ($9AE) is entered to set up a data file for reading. It 
beg:ins by calling SETFCB to set some standard file information into 
the FCB. It continues by setting up the FCB with various other 
parameters to read the first data sector in the file. This sector is read 
via the RDNSO routine. When the sector has been read into the 
sector buffer, the code returns to the caller. 

DFOAPN 

DFOAPN ($BEC) is entered to open a file for Append. 

1 ) Pop the stack to determine if the file has been found in the 
directory. If the file was not found exit via ERFNF. 

2) if the file was created by DOS 1 , then exit via ERAPO. 

3) Insure the file is not locked by calling TSTLOCK. 

4) Insure the diskette is not write protected by calling 
OPVTOC. 

5) Allocate a new sector for the start of the Append chain by 
calling GETSECTOR. 

6) Save the sector number of the sector obtained in FCBSSN so 
that it will be available when the file is closed. 

32 



CHAPTER EIGHT 



7) Continue opening the file as if it were being opened for 
Output at DHFOX2. 

DI=OOUT 

The DFOOUT ($911) routine is entered when opening a file for 
Output. 

1 ) Pop the stack to determine if the file was found in the 
directory. 

2) If the file was found, then delete it via the XDELO ($C53) 
routine. 

3) If the file was not found, then make a new entry in the directory 
via the code at DFOXl ($9 ID). 

4) Allocate a data sector for the file via the GETSECTOR 
routine. 

5) Put the necessary information about the file into the directory 
and write the directory sector back to the disk. 

6) Continue at DHFOX2. 

Dlf1FOX2 

DHFOX2 ($97C) is entered to finish the Open process for files that 
are being opened for Output or Append. 

1) Finish initializing the FCB via SETFCB. 

2) If the TSTEKDS routine determines that the file name being 
opened is DOS. SYS, then write out DOS via the WRTDOS 
routine. 

3) Exit via GREAT. 

SIITFCB 

The SETFCB ($995) routine is used in the various Open file routines 
to place certain common data into the FCB. 



33 



Chapter Nine 

FMS 

CLOSE 

ROUTINES 



The; FMS close routine is called directly by CIO via the FMS Device 
Vector Table, DFMSDH at $7CB. 

DFMCLS 

Address -$B15 

Entry Registers - A = Don't Care. 

X = lOCB number times 16. 

Y = Don't Care. 
Exit Registers - A = Unknown. 

X = Unknown. 

Y = Unknown. 

Functions: 

1) Initialize via call to SETUP. 

2) If the file was not opened for some form of output (Output, 
Update or Append) then clear the FCB open flag, FCBOTC and 
exit via FGREAT. 

3) If the FCBFLG indicates that the file has not acquired sectors, 
then continue at CLUPDT to close the Update file. 

4) Write the last data sector via WRTLSEC. 

5) Read the file's directory sector into the directory buffer via the 
RRDIR routine. 

6) Get the sector count from the directory. 

7) If the file was opened for Output (i.e. it is not open for 
Append), then continue at CLOUT. 

8) Read all the data sector of the file until the end-of-file sector 
is found. 

9) Place the sector address of the start of the Append chain into 
the link sector field of the (old) end-of-file sector. 

10) Continue at CLOUT. 

34 



CHAPTER NINE 



CLOUT 

The CLOUT ($B50) routine is entered to finish closing a file that had 
been opened for Output or Append. 

1 ) The sector count field of the directory is updated. 

2) The open for output flag is turned off. 

3) The file in use flag is set. 

4) The directory sector is written back to the disk by the DRTDIR 
routine. 

5) The VTOC sector is written back to the disk by the 
WRTVTOC routine. 

6) The FCB open code flag, FCBOTC, is cleared to zero. 

7) Exit via FGREAT. 

CLUPDT 

The CLUPDT ($B75) is called to finish the closing of a file that had 
been opened for Update. 

1 ) If the current sector in the sector buffer has been modified 
then write it back to the disk via the WRCSIO routine. 

2) Clear the FCB open flag, FCBOTC, to zero. 

3) Exit via FGREAT. 



35 



Chapter Ten 

GET BYTE 
ROUTINE 



The FMS GET BYTE routine, DFMGET, is called directly by CIO 
via tlie FMS Device Vector Table, DFMSDH at $7CB. The GET 
BYTE routine's function is to get and return the next sequential data 
byte to CIO. 

DFMGET 

Address - $ABF 

Entry Registers - A = Don't Care. 

Y = lOCB number times 16. 
X = Don't Care. 

Exit Registers - A = Unknown. 

Y = Unknown. 
X = Unknown. 

Functions: 

1 ) Initialize via the SETUP routine. 

2) If the FCB is opened for Directory read, then go to 
GDCHAR. 

3) If the current sector is empty, attempt burst I/O (see Burst I/O 
section), then continue with number four. 

4) Read the next sector via the RDNXTS routine. If the read 
sector operation did not return an end-of-file condition, then 
continue at step three, else exit via ERREOF (end-of-file error). 

5) Get the data byte from the sector and place it in SVDBYT for 
the exit routines. 

6) If the next byte in the file is the end-of-file byte, exit via 
RETURN with the impending end-of-file condition code ($03), 
else exit via GREAT. 



36 



Chapter Eleven 

PUT BYTE 
ROUTINE 



The FMS PUT BYTE routine, DFMPUT, is called directly by CIO 
vin the FMS Device Vector Table, DFMSDH at $7CB. The PUT 
B^fTE routine's function is to place the single data byte transmitted by 
CIO into the data sector. 

DIFMPUT 

Address -$99C 

Entry Registers - A = The "put data" data byte. 

X = The lOCB number times 16. 

Y = Don't Care. 
Exit Registers - A = Unknown. 

X = Unknown. 

Y = Unknown. 

Functions: 

1 ) The data byte in the A register is saved in SVDBYT. 

2) SETUP is called to initialize for this operation. 

3) If the caller was not CIO, then prevent a burst I/O operation 
from occurring. 

4) If the file was not opened for output, then exit via ERDVDC 
(device command error). 

5) If the current data sector is full, write the sector via WRTNXS, 
then attempt burst I/O (see BURST I/O section). If a burst I/O 
operation did take place, then get the next byte after the area 
just written by burst I/O and place it into the SVDBYT cell. 

6) Increment the sector data byte count. 

7) Move the data byte from SVDBYT to the next available data 
byte in the sector. 

8) Set the sector modified flag in the FCB. 

9) Exit via GREAT. 



37 



Chapter Twelve 

BURST I/O 



The CIO is designed to fill or empty a large user buffer with data bytes 
sent to or received from a device handler, a byte at a time. To fill a 
thousand-byte buffer, CIO would have to call FMS one thousand 
times in rapid succession. While the process is simple and easy to 
implement by both CIO and the Device Handlers, it can be very 
slow. This is particularly true in the case of FMS which has a great 
deal of overhead code to go through each time it is called. FMS 
circLimvents most of the CIO/FMS calls for large data transfers via the 
BURST I/O routines. 

Burst I/O operates by reading or writing data sectors directly into 
the user buffer (Figure 1, data path I). There are a number of tests 
that must be passed before a burst I/O operation can take place. If any 
of the tests fail, then the CIO/FMS data transfer reverts to the normal 
mode of operation. 

When the PUT BYTE routine is called, it will call the WTBUR 
($A1F) routine when it is ready to start filling a new data sector. 
WTBUR will not allow a burst I/O operation to happen if the file has 
been opened for Update. If the file has not been opened for Update, 
then WTBUR goes to the common read/write burst I/O test routine, 
TBL'RST at $A28. If the file has been opened for Update, then exit 
Burst I/O indicating that a Burst I/O did not happen. When WTBUR 
calls TBURST, it has the A register set to non-zero to indicate that it 
is write. 

When the GET BYTE routine is called, it will call the RTBUR 
($A26) routine when it is ready to read a new data sector. RTBUR 
indicates that it is read by setting the A register to zero and then 
enters TBURST. 

TBURST 

1 ) Save the A register in BURTYP. This value will indicate if 
the burst operation is a read or a write. 

2) If the I/O command in the lOCB is for text I/O (a transfer 
that is to end when the Atari end-of-line ($9B) character is 
transferred), then TBURST will exit indicating (carry set) that a 
burst I/O operation did not occur. 

38 



CHAPTER TWELVE 



3) If the user buffer length in the lOCB is not at least a full 
sector in size, then exit without doing a burst I/O. 

4) If all the above tests pass, then perform a burst I/O operation. 
The first step in the burst I/O operation is to change the zero 
page sector buffer pointer, ZXBA ($47) from the FMS sector 
buffer address to the user buffer address. 

5) If the operation is read, then read the next sector via RDNXTS. 
If the read sector operation produced an end-of-file, then go to 
BUREOF, else go to BBINC. 

6) If the operation is write, then the area in the user buffer, 
where the three bytes of data sector control information is to be 
placed, will be saved. The data will be written via the WRTNXS 
routine. The saved user data will then be copied back into the 
user buffer. The code then continues at BBINC. 

BBINC 

The BBINC routine is entered after a single burst I/O sector has been 
read or written. BBINC updates data counters in the FCB and in the 
\OCB and tests for the end of the Burst I/O. 

1 ) The zero page sector buffer pointer is incremented by the 
length of data in a sector (125 or 253). 

2) The user buffer length is decremented by the length of data in 
a sector. 

3) The TBLEN routine is called to determine if there is enough 
room left in the user buffer to read or write another full sector 

( 128 or 256 bytes). If another sector can be read or written, then 
the process repeats at NXTBUR ($A3E). 

4) If there is not enough room in the user buffer to perform 
another full sector read or write, then BUREOF is entered. 

BUREOF 

1) The final address in the zero page sector pointer, ZSBA ($47), 
is moved to the lOCB buffer address field. 

2) The value in the zero page sector buffer pointer is restored by 
the SSBA routine. 

3) The caller is returned to with the carry cleared to indicate 
that a burst I/O operation has happened. 



59 



Chapter Thirteen 

READING 

THE DIRECTORY 

AS A FILE 



A formatted subset of the data in the Directory can be read as if the 
Direi:tory were a disk file. This is accomphshed by using the open 
directory code ($02) in the lOCB ICAUXl byte. When FMS 
recognizes this code in the Open routine (at $8B1), it will go directly 
to the LISTDIR routine. The LISTDIR routine prepares the FCB for 
reading the directory as a file. The GET BYTE routine will recognize 
the read directory condition from information stored in the FCBOTC 
field (see $AC2) and go directly to the directory read character I/O 
routine GDCHAR. 

LISTDIR 

Address - $DAD 

Entry Registers - A = Don't Care. 

X = lOCB and FCB number times 16. 

Y = Don't Care. 
Exit Registers - A = Unknown. 

X = Unknown. 

Y = Unknown. 

Functions: 

1) The TEMP4 byte is used to count the characters that have 
been transmitted by GDBYTE from the formatted line buffer. 
LISTDIR sets this value to zero to indicate the start of a new 
formatted line. 

2) The SFDIR routine is called to start a wild card search for the 
file name in the directory. 

3) If a match is found then FDENT is called to format the entry 
and prepare for the GDBYTE calls. Exit via GREAT. 

4) If a match is not found, then LDCNT is called to prepare to 
send the xxx FREE SECTORS line. 



40 



CHAPTER THIRTEEN 



GDCHAR 

G1X:HAR ($DB9) is entered from GET BYTE to get a single data 
byte from a formatted directory line. 

1) The TEMP4 flag is tested. If the value is negative, then all 
formatted information has been transmitted. Exit is via the 
ERREOF (end-of-file error) exit. 

2) The value in TEMP4 is used as an index into the formatted 
line buffer to get the next character. The character is placed into 
SVDBYT for loading into the A register by the RETURN 
routine. 

3) The character retrieved from the buffer is examined for the 
EOL ($9B) character. 

4) If the character is not an EOL, then exit is via GREAT. 

5) If the character was an EOL, then the line length is examined 
to see if the line was a directory entry line (i.e. , if the length was 
17) or the final xxx FREE SECTORS. 

6) If the line was the final line, then TEMP4 is set to a negative 
value ($80) to indicate that all formatted lines have been sent. 
Exit is via GREAT. 

7) If the line was not the final line, then CSFDIR is called to 
find the next matching file name. 

8) If a file name match is found, then FDENT is called to format 
the found entry into the formatted line buffer. Exit is via 
GREAT. 

9) If a file name match is not found, then go to LEXI^NT to 
format the final line. 

LDCNT 

LIX^NT ($DE9) formats the final line of a directory read. 

1) Read the VTOC. 

2) Get the free sector count from the VTOC and convert it to 
ATASCII via the CVDX routine. 

3) Move the FREE SECTORS message to the formatted line buffer. 

4) EXIT is via FGREAT. 

FDENT 

The FDENT ($E21) routine formats the current directory entry into 
the formatted line buffer for subsequent reading by GDBYTE. 

1) The directory flag is checked for the file locked condition. If 

41 



the file is locked, then the "*" is placed in the formatted line. 

2) The file name is moved from the directory entry to the 
formatted line. 

3) The file sector count is converted to AT ASCII and placed in 
the formatted line. 

4) The EOL character is placed in the formatted line. 

5) Exit is via the RTS instruction. 



Chapter Fourteen 

SECTOR 

I/O 
ROUTINES 



The FMS performs sector I/O by calling the SIO routine in the OS 
ROM (Figure 1, control path 3). All sector I/O calls in the FMS occur 
frorri the BSIO routine. There are several other routines that are 
designed to set up information for BSIO. These routines deal with 
reading and writing sectors of a particular type such as data sectors, 
directory sectors, and the VTOC sector. 

BSIO 

Address — $76C 

Entry Registers - A = Sector number most significant byte. 

Y = Sector number least significant byte. 
X = If 1, then 128 byte I/O (810 drive). 

If 2, then 256 byte I/O (815 drive). 
Exit Registers - A = Status byte from DCB. 

Y = Unknown. 

X = lOCB and FCB number times 16. 

42 



CHAPTER FOURTEEN 



Functions: 

1) The sector number is stored in the DCB from the A,Y register 
pair. The EXHB is the interface control block for SIO calls. 

2) If the carry is clear, then the DCB is set up for read data. If 
the carry is set, then the DCB is set up for write data. 

3) The serial bus ID for the disk, and the disk timeout values are 
placed into the DCB. 

4) The error retry counter, RETRY, is set for four retries. 

5) The I/O data length is set to 128 or 256 depending upon the 
data in the X register. 

6) The serial I/O routine ($E459) is called to execute the I/O. 

7) If the I/O operation was good, then the X register is loaded 
with the lOCB (and FOB) number times 16 from the CRFCB 
cell and the status byte from the DCB is loaded into the A register. 
Return is via the RTS instruction. 

8) If the I/O operation was bad, then the retry counter is 
decremented. If the retry value is positive, then the I/O is retried. 
If the value is negative, then the routine is exited in the manner 
described in step seven. 



Ds;io 

The DSIO routine is called to perform data sector I/O operations. 
Address -$11F7 
Entry Registers - A = Sector number most significant byte. 

Y = Sector number least significant byte. 
X = lOCB and FCB number times 16. 

Exit Registers — A= I/O condition code. 

Y = Unknown. 

X = lOCB and FCB number times 16. 

Functions: 

1 ) The sector buffer address is obtained from the zero page sector 
buffer pointer ZSBA ($47) and placed in the DCB buffer address 
field, DCBBUF. 

2) The drive type byte is loaded into the X register from DRVTYP. 
If the drive is an 810, then the value will be one. If the drive is 
an 815, then the value will be two. 

3) BSIO is called. 

4) The DSIO caller is returned to via the RTS instruction. 

43 



CHAPTER FOURTEEN 



RDDIRAndWRTDIR 

The RDDIR and the WRTDIR routines are used to perform Directory 
sector I/O operations. The RDDIR entry ($106E) sets the carry to 
indicate read. The WRTDIR entry ($1071) clears the carry to indicate 
write. Both of the routines continue at DIRIO. 

DIRIO 

1) Save the read/write flag (carry sense) on the stack. 

2) Set the address of the directory buffer into the DCB buffer 
field, DCBBUF. 

3) The CDIRS cell contains the number of the directory sector 
to be read or written. This value ranges from zero to seven. The 
DIRIO routine creates the actual sector number to read or write 
by adding $169 to the CDIRS value. The resulting sector number 
is placed in the A, Y register combination. 

4) Continue at DSYSIO. 

RDWOC And WRTVTOC 

The RDVTOC and WRTVTOC routine are called to initiate I/O to 
and from the VTOC sector. The RDVTOC routine ($108B) first 
checks the write required byte in the VTOC sector buffer. If the value 
of this byte is not zero, then the VTOC is already in the buffer (and 
has been changed). If the VTOC is already in the buffer, then the 
read does not have to be done; therefore, the RDVTOC routine will 
return to the caller. If the write-required byte is zero, then RDVTOC 
will clear the carry to indicate that the operation is read. The 
WRTVTOC routine ($1095) sets the write required byte to zero, then 
sets i:he carry to indicate a write operation. Both Rt)VTOC and 
WRTVTOC continue at VTIO. 

VTIO 

1 ) The read/write flag is pushed onto the stack. 

2) The VTOC sector buffer address is moved from the zero page 
drive buffer address pointer ZDRVA ($45) to the DCB buffer 
pointer, DCBBUF. 

3) The A,Y register combination is loaded with the VTOC 
sector number ($168). 

4) Continue at DSYSIO. 

DSYSIO 

1 ) The read/write sense is popped from the stack. 

44 



CHAPTER FOURTEEN 



2) The drive type value is loaded into the X register from 
DRVTYP. 

3) BSIO is called. 

4) If the I/O operation was good, then return to the caller via the 
RTS instruction. 

5) If the I/O operation was bad, the exit via the ERRSYS exit 
(fatal system I/O error). 

OI>VTOC 

The OPVTOC routine ($10BF) is used by various FMS routines to 
insure that the diskette is not write protected before executing functions 
that will write to the disk. This routine will read the VTOC via 
RDVTOC and then attempt to write the VTOC via WRTVTOC. If 
the diskette is write protected, the WRTVTOC will cause an I/O 
error exit (error number 144). If the diskette is not write protected, 
then the routine will return to the caller. When OPVTOC does 
return to the caller, the current disk VTOC is in the drive buffer. 



45 



Chapter Fifteen 

FILE NAME 
DECODE 
ROUTINE 



The FNEXI^ODE routine is used to transform the user suppUed file 
name into a form that is usable in FMS for wild card searching of the 
direc:tory. The primary and extension parts of the user file name are 
padded with blanks and question marks as required. The following 
examples show the types of transform performed by FNEXDODE: 



User File Name 




Transformed File Name 


D:*.* 




77777777777 


Dl:GLOP.* 




GLOP ??? 


Dl:GLOP.BAS 




GLOP BAS 


D2:*.ASM 




????????ASM 


D:GL?P.S* 




GL?P S?? 


D1:G* 




G7777777 


FNC»CODE 






Address - $E9E 






Entry Registers - 


-A 


= Don't Care. 




X 


= lOCB and FCB number times 16. 




Y 


= Don't Care. 


Exit Registers — 


A 


= Unknown. 




X 


= lOCB and FCB number times 16. 




Y 


= Unknown. 



Functions: 

1 ) The user file name buffer is searched for the colon (:) delimiter. 
If the delimiter is not found within 256 characters then exit to 
ERRFN routine (file name error). 

2) The FMS file name buffer, FNAME, is cleared to blanks. 

3) The EXTSW byte is set to zero. When EXTSW is zero, the 
primary file name field is being processed. When EXTSW is 

46 



CHAPTER FIFTEEN 



minus, then the extension file name field is being processed. 

4) The next character in the user file name buffer is examined. 

5) If the character is an asterisk ('), then the field is padded with 
question mark characters to the end of the field. 

6) If the character is a period and the extension field is being 
processed, then exit via the RTS instruction. 

7) If the character is a period and the primary field is being 
processed, then switch to the extension field processing. 

8) If the character is a question mark, then put it into the FN AME 
via FDSCHAR. 

9) If the character is alphanumeric (A through Z, or through 
9), then put it into FN AME via FDSCHAR. 

10) If the character is none of the above, then assume that end 
of the filename has been found and exit via the RTS instruction. 

11) If a character was stored, then continue at step four. 

FDSCHAR 

1 ) If the character counter register, X, indicates that the primary 
field is full, then exit without storing the character. 

2) If the character counter register, X, indicates that the extension 
field name is full, then exit without storing the character. 

3) Store the character into FN AME indexed by the X register. 

4) Increment the X register. 

5) Return to caller via the RTS instruction. 



47 



Chapter Sixteen 

DIRECTORY 
SEARCHING 



The Directory search routine searches the directory entries for a file 
name that matches the name in FNAME. The routine has two entry 
points: SFDIR which is used to begin the search at the start of the 
directory, and CSFDIR, which is used to continue searching the 
directory at the entry just past the previously found matching entry. 

The routines have five memory cells that they use for controlling 
the search operation: DHOLES, DHOLED, CDIRS, CDIRD and 
SFNUM. The CDIRS cell contains the current relative directory 
sector number (zero through seven). The CDIRD cell contains the 
displ acement into the directory sector of the current entry. DHOLES 
gives the relative directory sector number (zero through seven) of the 
first hole or available entry in the directory. TTie DHOLED cell gives 
the displacement to the first available entry that is the hole. The 
SFNUM cell is used to contain the current file number of the entry 
being examined. The value in SFNUM will be from zero through 63. 

If the value of DHOLES is $FF at the end of the search, then the 
directory is full. 

The directory search routine will exit with the carry clear if a 
match was found. It will exit with the carry set if no matching entry 
was found. 

SFDIR 

The SFDIR routine ($F21) is called to start searching the directory at 
the start of the directory. 

1) Initialize DHOLES, CDIRS, SFNUM to $FF. 

2) Initialize CDIRD to $70. 

3) Continue at CSFDIR. 

CSFDIR 

The CSFDIR routine ($F3 1 ) is called to continue searching the 
directory. 

1) Increment the file number, SFNUM. 
48 



CHAPTER SIXTEEN 



2) Increment CDIRD by the size of a directory entry (16). 

3) If the CDIRD is now greater than, or equal to, 128 ($80) then 
increment CDIRS by one. If the value of CDIRD is now eight, 
then exit with the carry set to indicate that a match was not 
found. If CDIRD is less than eight, then read the next directory 
sector via RDDIR. Set CDIRD to zero. 

4) If the directory entry flag field is zero then the end of the used 
portion of the directory has been reached. If a hole has not been 
found, then mark this entry as a hole. Exit with the carry set to 
indicate that the file was not found. 

5) If the directory entry flag field indicates that the file is open 
for output, then skip this entry. 

6) If the directory entry flag field indicates that the file has been 
deleted, and a hole has not been found, then mark this entry as a 
hole and continue searching the directory. 

7) If the file is in use, then check the file name in the directory 
entry for a match with the name in FNAME. Wild card characters 
in FNAME (question marks) are assumed to match the 
corresponding characters in the directory entry file name. 

8) If the names match, then exit with the carry clear to indicate 
that a match was found. 

9) If a match was not found, then continue to search the 
directory. 



49 



Chapter Seventeen 

WRITE 

NEXT 

SECTOR 



The write next sector routine, WRTNXS, is used to write a data 
sector to disk. 

Address - $F94 

Entry Registers - A = Don't Care. 

X = lOCB and FCB number times 16. 

Y = Don't Care. 
Exit Registers — A = Unknown. 

X = lOCB and FCB number times 16. 

Y = Unknown. 

Functions: 

1 ) If the file has been opened for update, and the sector has not 
been modified, then do not write the sector. Read the next data 
sector and then return to caller. 

2) If the file has been opened for update, and the sector has been 
modified, then write the current sector. Read the next data 
sector into the sector buffer and return to the caller. 

3) If the file is not opened for update, then allocate a new sector 
to the file by calling GETSECTOR. 

4) Move the sector byte count from the FCB FCBDLN field to 
the data sector byte count field. 

5) Move the address of the newly acquired sector from the FCB 
FCBLSN field into the link field of the current data sector. 

6) Write the current sector to the disk via WRCSIO. 

7) If the I/O was bad, mark the FCB by placing a zero value into 
FCBOTC as closed and exit via RETURN with the I/O error 
number as the return code. 

8) If the I/O was good, then increment the FCB sector counter 
field, FCBCNT. 

50 



9) Call MVLSN to move the sector number of the link sector 
number field of the FCB, FCBLSN, to the current sector number 
field of the FCB,FCBCSN. 

10) Set the current data length field of the FCB, FCBDLN, to 
zero. 

11) Set the maximum data length field of the FCB, FCBMLN, 
to 125 (if 810 drive) or 253 (if 815 drive). 

12) Return to user via the RTS instruction. 



Chapter Ei 



READ 

NEXT 

SECTOR 



Th«; read next sector routine, RDNXTS, reads the next sector in the 
file sector chain into the sector buffer. If there are no more sectors in 
the chain, then the routine returns with the carry set to indicate end- 
of-file. If the routine returns with the carry clear, then the next sector 
has been read. 

RDNXrS 

Address -$100F 

Entry Registers - A = Don't Care. 

X = lOCB and FCB number times 16. 

Y = Don't Care. 
Exit Registers - A = Unknown. 

X = lOCB and FCB number times 16. 

Y = Unknown. 

Functions: 

1) If the file has been opened for Update, then WRTNXS is 

51 



CIHAPTER EIGHTEEN 



called to write the current sector if it has been modified. 

2) If the FCB link sector number field, FBCLSN, is zero then 
there are no further sectors to read. Return to the caller with the 
carry set to indicate that the end-of-file has been reached. 

3) Call MVLSN to move the FCB link sector number field, 
FCBLSN, the FCB current sector number field, FCBCSN. 

4) Call RWCSIO with the carry set to read the next sector. 

5) If the I/O operation was bad, exit via the ERRIO exit (I/O 
error) . 

6) Insure that the file number in the sector just read agrees with 
the file number in the FCB. If the file numbers are not the same, 
exit via the ERFNMM exit (file number mismatch). Note: if the 
routine was called by delete, return to delete indicating end-of- 
file. 

7) Move the link sector number from the data sector to the FCB 
link sector field in the FCB, FCBLSN. 

8) Move the sector data length information from the data sector 
to the FCB maximum data length field, FCBMLN. 

9) Reset the FCB data length field, FDBDLN, to zero. 

10) Return to the caller with the carry clear to indicate that a 
sector has been read. 



52 



Chapter Nineteen 

GET AND 

FREE 

SECTOR 

ROUTINES 



TbiC get sector routine, GETSECTOR, is called when a new sector is 
needed. The routine searches the bit map in the VTOC for a free 
sector. The sector found is deallocated from the bit map and the 
sector number is returned to the caller. The free sector routine, 
FR.ESECT, is given a sector number to be freed. FRESECT locates 
the required bit map bit in the VTOC and turns it on (sets it to one). 
The sector is now eligible for reuse. 

GETSECTOR 

Address -$1106 

Entry Registers - A = Don't Care. 

X = lOCB and FCB number times 16. 

Y = Don't Care. 

Exit Registers - A = Unknown. 

X = ICXIlB and FCB number times 16. 

Y = Unknown. 

Functions: 

1 ) The Y register is used as an index into the bit map bytes. 

2) The bit bytes are examined sequentially from the first bit map 
byte to the last bit map byte until a non-zero byte is found. The 
displacement to this byte is saved in TEMPI. 

3) If no bits are found in the bit map, then the ERRNSA exit 
(no sectors available) is taken. 

4) The number-of-sectors-available-field, in the VTOC, is 
decremented by one. 

5) The VTOC write required byte in the VTOC is set to a non- 



53 



CHAPTER NINETEEN 



zero value to indicate that the VTOC has been changed and 
must be written back to the disk. 

6) The non-zero bit map byte that was found in the bit map 
search is retrieved. The bits in this byte are shifted left until a bit 
moves into the carry flag. The carry is then set clear and the bits 
shifted back to their original position. The byte with the newly 
allocated sector bit turned off is placed back into the bit map. 

7) The number of bits shifted and the index to the bit map byte 
are used to develop the sector number represented by the Ijit. 

8) The sector number is stored in the FCB link sector field, 
FCBLSN. 

9) The user then returned to via the RTS instruction. 

FRIESECT 

Address -$10C5 

Entry Registers - A = Don't Care. 

X = lOCB and FCB number times 16. 

Y = Don't Care. 
Exit Registers - A = Unknown. 

X = lOCB and FCB number times 16. 

Y = Unknown. 

Furictions: 

1 ) The sector to be freed is in the FCB current sector field, 
FCBCSN. If the sector number is zero, then FRESECT exits 
back to the user via the RTS instruction. 

2) The sector number is divided by eight to determine the bit 
map byte which represents the sector. The remainder from this 
division represents the bit within the byte. 

3) The byte is retrieved from the bit map, the bit is turned on, 
and the byte placed back into the bit map. 

4) The number of available sectors field in the VTOC is 
incremented by one. 

5) The VTOC write required byte is set to non-zero to indicate 
that the VTOC has been changed and needs to be written back 
to the disk. 

6) The caller is returned to via the RTS instruction. 



54 



Chapter Twenty 

THE 
BOOT PROCESS 



When the Atari computer is turned on, the routines in the OS ROM 
will (under certain conditions) read the first sector from the disk in 
drive one into memory. It will then examine certain specific locations 
in this record to decide how to boot the disk. In the following 
discussion, refer to Figure 20-1. The OS ROM code will load BRCNT 
consecutive sectors (starting with sector one) onto memory, starting 
at the address contained in BLDADR. When the OS ROM code has 
finished this task, it will make a JSR call to the code that is seven 
bytes into the start of the boot area. In the case of FMS, this is the 
JMP XBCONT instmction at $706. The XBCONT code will continue 
the boot load process. 

The XBCONT code examines the DFSFLG to see if a DOS. SYS 
file exists. If the file exists, then the sector number of the first sector 
in DOS. SYS will be in DFLINK. The routine will then read all the 
sectors in the chain starting at DFLINK into the memory area pointed 
to by DFLADR. When the entire DOS. SYS file is read into memory, 
X13CONT returns to the OS ROM code. 

The OS ROM code will eventually vector through the BINTADR 
so that the FMS can initialize itself. In the DOS 2. OS system, 
BINTADR points into the DUP.SYS code. DUP.SYS then receives 
control from the OS ROM rather than the FMS. One of the tasks that 
DUP.SYS performs during its initialization is to call the FMS 
initialization routine. 

XBCONT 

The XBCONT routine ($714) is entered by the OS ROM code during 
tbie boot process to allow the boot process to continue in the manner 
best suited for the code being booted. 

Functions: 

1) If the DFSFLG indicates that a DOS. SYS file does not exist, 
then the OS ROM is returned to with the carry set to indicate 
that the boot has failed. 

55 



CHAPTER TWENTY 



2) The address contained in DFLADR is moved to the zero page 
address pointer, ZBUFP, and to the DCB buffer pointer field, 
DCBBUF. 

3) The sector number contained in DFLINK is loaded into the 
A, Y register pair, the carry is cleared to indicate read, and BSIO 
is called to read a DOS. SYS sector. 

4) The next sector link is obtained from the link field of the data 
sector just read. 

5) If the sector link value is zero, then the DOS. SYS end-of-file 
has been reached. The OS ROM will be returned to with the 
carry clear to indicate that the boot read was good. 

6) If the sector link value is not zero, then the zero page buffer 
pointer and the EXHB buffer pointer are incremented by the 
amount of data in the sector (125 for 810 drives, 253 for 815 
drives). 

7) The process continues by reading the next sector into 
memory. 



Sector 1 



Sector 2 



$700 



$780 



Sector 3 $800 



$700 


BFLAG 


Flag( = 0) 


$701 


BRCNT 


Number of Consecutive Sectors to Read 


$702 


BLDADR 


Address to Load Boot Sectors at 


$704 


BIWTARR 


Initialization Address 


$706 


JMPXBCONT 


Boot Continue Vector 


$709 


SABYTE 


Number of Sector Buffers to Allocate 


$70A 


DRVBYT 


Drive Bits 


$70B 




Unused 


$70C 


SASA 


Buffer Start Address 


$70E 


DFSFLG 


DOS Flag 


$70F 


DFLINK 


Sector Pointerto DOS.SYS File 


$711 


BLDISP 


Displacement in Sector to Sector Link 


$712 


DFLADR 


Address of Start of DOS.SYS File 
Figure 20-1 

Boot Records 



56 



Chapter Twenty-One 

MAINTAINING 

THE 
BOOT RECORD 



The boot record (sector 1) contains information about the DOS. SYS 
file. When LX)S.SYS is opened for output, FMS will write all of FMS 
out to the disk as part of the open process. It will also modify sector 
zero to indicate that a CXDS.SYS file exists and to indicate where on 
the disk it is. If DOS. SYS is ever Deleted or Renamed (to something 
not DOS. SYS), then the boot record must be modified to indicate 
that a DOS. SYS file does not exist. If a file is ever renamed to 
EX)S.SYS, then the boot record is modified to point to the new 
DOS. SYS file. 

WRTDOS 

The WRTDOS routine ($120A) is used to write a new DOS. SYS file 
to disk and to update the boot record to indicate that a EXDS.SYS file 
exists. 

Functions: 

1 ) The sector number which is contained in the FCB sector 
number link field, FCBLSN, is used as the first sector of the 
DOS. SYS file. This sector number is placed in the boot record 
area in page seven along with the other necessary information. 

2) Sectors one, two, and three are written from the memory area 
from $700 through $87F. 

3) The FMS is written to the EXDS.SYS via the WDO routine. 

4) Exit is via GREAT. 

WDO 

Tl-ie WDO routine ($1267) is used to write the FMS to the DOS.SYS 
file. 

Functions: 

1 ) The address contained in DFLADR is moved to the zero page 



57 



CMAPTER TWENTY-ONE 



buffer pointer, ZBUFP. 

2) The FMS is copied from its area in memory to the file sector 
buffer in 125 byte chunks. 

3) The buffers are written to disk by the WRTNXS routine. 

4) The process continues until the entire FMS area has been 
written. 

5) The caller is returned to via the RTS instruction. 

DliLDOS 

Tbe DELIX)S routine ($1219) is used to modify the boot record to 
indicate that DOS. SYS does not exist. 

Functions: 

1) The DFSFLG is set to zero to indicate that DOS. SYS does not 
exist. 

2) The area from $700 to $87F is written to sectors one, two, 
and three. 

3) The caller is returned to via the RTS instruction. 



58 



ATARI 
DOS 
2.0S 



Copyright © 1982 Optimized Systems Software, Inc. 

Thii listing is protected against unauthorized reproduction by the Copyright Law of the United 
Stales. Any reproduction utiUzed for profit or other commercial advantage is precluded without 
the specific prior written authorization of Optimized Systems Software, Inc., the owner of the 
cop /right. Any such reproduction does not constitute fair use and may subject the individual to 
both civil and criminal penalties. Federal Law provides for a maximum fine of $10,000 or 
imprisonment for not more than one year, or both, for infringement of this copyright. 

Contact the President, Optimized Systems Software, Inc., 10379 Lansdale Avenue, Cupertino, 
California, 95014, prior to reproducing or utilizing any portion of this listing. Any attempt to 
change the form of publication of this listing, that is, rendering it into machine-readable form or 
othjrwise, is a precluded reproduction if done for profit or other financial advantage. 

59 



ATARI DOS 2.0S 



FMS - 128/256 BYTE SECTOR {2.0S) 

Copyright and Author Notice 



0030 



1001 
1002 
1003 
1004 
1005 
1006 
1007 
1008 
1009 
1010 
1011 
1012 
1013 
1014 
1015 
1016 
1017 
1018 
1019 
1020 
1021 
1022 
1023 
1024 
1025 
1026 

1027 
1028 ; 

System Equates 



.PAGE " Copyright and Author Notice — 



COPYRIGHT (C) 1978,1979,1980,1982 
OPTIMIZED SYSTEMS SOFTWARE, 
CUPERTINO, CA. 

THIS PROGRAM MAY NOT BE REPRODUCED, 
STORED IN A RETRIEVAL SYSTEM, OR 
TRANSMITTED IN WHOLE OR IN PART, 
IN ANY FORM, OR BY ANY MEANS, BE IT 
ELECTRONIC , MECHANICAL, PHOTOCOPYING, 
RECORDING, OR OTHERWISE WITHOUT THE 
PRIOR WRITTEN PERMISSION OF 

OPTIMIZED SYSTEMS SOFTWARE, INC. 

10379 LANSDALE AVENUE 

CUPERTINO, CALIFORNIA 95014 (U.S. 



A.) 



PHONE: (408) 446-3099 



*********************************** 



PROGRAMMER PAUL LAUGHTON 
UPDATED: 19-AUG-80 



.*********************************** 



0000 



0700 
0043 
03 40 
0003 
03 00 
E453 
00 9B 
03 lA 
0020 
02E7 
1540 
0102 
00 DF 

0246 

000F 



1029 
1030 
1031 
1032 
1033 
1034 
1035 
1036 
1037 
1038 
1039 
1040 
1041 
1042 
1043 
1044 



.PAGE " System Equates" 
*********************************** 



FMSORG = 
FMSZPG = 
lOCBORG = 
LMASK = 
DCBORG = 
DHADR = 
EOL 

DEVTAB = 
ZICB 

LMADR = 
DUPINIT = 

1045 STAR 

1046 OSBTM = 



1047 DSKTIM 



1048 TIMOUT = 



$700 

?43 

$340 

03 

$300 

$E453 

$9B 

$31A 

$20 

$2E7 

$1540 

$102 

$DF 

$246 

15 



;LINK MASK 



rlNIT ADDR FOR DUP 

; STACK LOC FOR PUT BYTE 

;HI BYTE OF ADDR LESS THAN OS 

SPACE 
rADDR OF OS WORST CASE DISK 

TIME OUT 
;TIME OUT VALUEE OF 15 SECS. 



0000 


1049 


0000 


1050 




1051 




1052 




1053 




1054 




1055 




1056 



.PAGE " lOCB" 
*= lOCBORG 

lOCB - 10 CONTROL BLOCK 
THERE ARE 8 1/0 CONTROL BLOCKS 
1 lOCB IS REQUIRED FOR EACH 
CURRENTLY OPEN DEVICE OR FILE 



60 



ATARI DOS 2.0S 



034» 
0341 
034:2 
0343 
0344 
0343 
034'5 
03413 
0349 
034A 
034:3 
03 40 
0340 
034E 
034F 
0010 

0350 



0001 
0002 
0003 
0004 
0005 
0006 
000 7 
0008 
00e9 
00eA 

00eB 
00ec 
00eD 

00i'E 
00CIE 
00C1F 



0001 
00(12 



1057 lOCB 








1058 ICHID 


*— 


*+l ; 


DEVICE NUMBER 


1059 ICDNO 


*— 


*+l 


DEVICE HANDLER 


1060 ICCOM 


*— 


*+l 


I/O COMMAND 


1061 ICSTA 


*a 


*+l ; 


I/O STATUS 


1062 ICBAL 


*s 


*+l 




1063 ICBAH 


* — 


*+l ; 


BUFFER ADR (H,L) 


1064 ICPUT 


*— 


*+2 


PUT CHAR DH ADDR 


1065 ICBLL 


*— 


*+l 




1066 ICBLH 


*ss 


*+l 


BUFFER LEN (H,L) 


1067 ICAUXl 


*s 


*+l ; 


AUX 1 


1068 ICAUX2 


* — 


*+l 


AUX 2 


1069 ICAUX3 


*— 


*+l 


AUX 3 


1070 ICAUX4 


*— 


*+l 


AUX 4 


1071 ICAUX5 


*— 


*+l 


AUX 5 


1072 ICAUX6 


*— 


*+l 


AUX 6 


1073 ICLEN 


= 


*-IOCB 




1074 ; 








1075 


*s 


*+ICLEN*7 


SPACE FOR 7 MORE lOCB'S 


1076 ; 








1077 ; ICCOM VALUE EQUATES 




1078 ; 








1079 ICOIN 


= 


$01 


•OPEN INPUT 


1080 ICOOUT 


= 


$02 


fOPEN OUTPUT 


1081 ICIO 


= 


$03 


;OPEN UN/OUT 


1082 ICGBR 


= 


$04 


;GET BINARY RECORD 


1083 ICGTR 


= 


$05 


; GET TEXT RECORD 


1084 ICGBC 


s 


$06 


;GET BINARY CHAR 


1085 ICGTC 


= 


$07 


;GET TEXT CHAR 


1086 ICPBR 


= 


$08 


;GET BINARY RECORD 


1087 ICPTR 


= 


$09 


;PUT TEXT RECORD 


1088 ICPBC 


= 


$0A 


;PUT BINARY CHAR 


1089 ICPTC 


= 


$0B 


;PUT TEXT CHAR 


1090 ICCLOSE = 


$0C 


;CLOSE FILE 


1091 ICSTAT 


= 


$0D 


;GET STATUS 


1092 ICDDC 


= 


$0E 


; DEVICE DEPENDENT 


1093 ICMAX 


= 


$0E 


;MAX VALUE 


1094 ICFREE 


= 


$0F 


;IOCB FREE INDICATOR 


1095 ; 








1096 ; ICSTA VALUE EQUATES 




1097 ; 








1098 ICSOK 


= 


$01 


; STATUS GOOD, NO ERRORS 


1099 ICSTR 


= 


$02 


;TRUNCAIATED RECORD 



lOCB 



00193 


1100 


ICSEOF 


= 


$03 


;END OJ 


FILE 


0080 


1101 


ICSBRK 


= 


$80 


; BREAK 


KEY ABORT 


00131 


1102 


ICSDNR 


= 


$81 


; DEVICE NOT READY 


0032 


1103 


ICSNED 


= 


$82 


;NON EXISTENT DEVICE 


0033 


1104 


ICSDER 


= 


$83 


;DATA ERROR 


0034 


1105 


ICSIVC 


= 


$84 


; INVALID COMMAND 


0035 


1106 


ICSNOP 


= 


$85 


; DEVICE/FILE NOT OPEN 


0036 


1107 


ICSIVN 


= 


$86 


; INVALID lOCB # 


00 87 


1108 
1109 


ICSWPC 


= 


$87 


;WRITE 


PROTECT 




1110 


r ZERO 


PAGE 


lOCB LABELS 






1111 


; 










0021 


1112 


ICDNOZ 


= 


ICDNO- 


-lOCB+ZICB 




0028 


1113 


ICBLLZ 


= 


ICBLL- 


■lOCB+ZICB 


BUF LEN 


0029 


1114 


ICBLHZ 


= 


ICBLH- 


-lOCB+ZICB 




0024 


1115 


ICBALZ 


= 


ICBAL- 


-lOCB+ZICB 


BUF ADDR 


0025 


1116 


ICBAHZ 


= 


ICBAH- 


-lOCB+ZICB 




0022 


1117 


ICCOMZ 


= 


ICCOM- 


-lOCB+ZICB 




0026 


1118 


ICPUTZ 


= 


ICPUT 


-lOCB+ZICB 


•PUT RTN ADDR 



61 



ATARI DOS 2.0S 



DCB 



17A0 
17A0 



0300 
0301 
030 2 
030 3 
0304 
0306 
0303 
030A 



005:2 
0050 
0053 
002 L 



000:. 

008]. 

008:! 

0083 
0084 
008 V 



1119 
1120 
1121 
1122 
1123 
1124 
1125 
1126 
1127 
1128 
1129 
1130 
1131 
1132 
1133 
1134 
1135 
1136 
1137 
1138 
1139 
1140 
1141 
1142 
1143 
1144 
1145 
1146 
1147 
1148 
1149 
1150 
1151 
1152 
1153 
1154 
1155 
1156 
1157 
1158 
1159 
1160 



.PAGE " DCB" 
*= DCBORG 

DCB - DATA CONTROL BLOCK 
THE DCB IS AN lOCB LIKE CONTROL 
BLOCK USED TO INTERFACE THE DISK 
FILE MANAGEMENT SYSTEM TO THE 
DISK HANDLER 



DCB 

DCBSBI *= 

DCBDRV *= 

DCBCMD *= 

DCBSTA *= 

DCBBUF *= 

DCBTO *= 

DCBCNT *= 

DCBSEC *= 



*+l 
*+l 
*+l 
*+l 
*+2 
*+2 
»+2 
*+2 



; SERIAL BUS ID 

;DISK DRIVE # 

; COMMAND 

,-I/0 STATUS 

;l/0 BUFFER ADDR (H,L) 

;TIME OUT CNT 

;l/0 BYTE COUNT 

;l/0 SECTOR NUMBER 



DCBCMD VALUE EQUATES 



DCBCRS = 
DCBCWS = 
DCBCST = 
DCBCFD = 



'R 
'P 
'S 
• 1 



;Read sector ($52) 

;Put sector ($50) 

;Status request ($53) 

r FORMAT DISKETTE ($21) 



*** SPECIAL NOTE: 

DCBCWS may be changed to 'W ($57) 
if desired to have disk perform 
a verifying read after each write. 
Disk write ( 'W) operations will take 
longer, but will be more reliable. 



DCBSTA VALUE EQUATES 

DCBSOK = $01 rSTATUS NORMAL 

DCBDNR = $81 ; DEVICE NOT READY 

DCBCNR = $82 ; CONTROLLER NOT READY 

DCBDER = $83 ;DATA ERROR 

DCBIVC = $84 ; INVALID COMMAND 

DCBWPR = $87 ; WRITE PROTECT 



030c: 
030c: 

004;: 

004!; 

0047 
0049 



004;. 
004;. 



ZERO PAGE 

1161 

1162 

1163 

1164 

1165 

1166 

1167 

1168 

1169 

15 

20 



.PAGE " ZERO PAGE" 
*= FMSZPG 



ZBUFP *= *+2 

ZDRVA *= *+2 

ZSBA *= *+2 

ERRNO *= *+l 



.•BUFFER PTR 
;ZERO PG DRIVE PTR 
;ZERO PG SECTOR BUF PTR 
TERROR NUMBER 



.INCLUDE #E: 

.INCLUDE *D:ATFMS1.SRC 



BOOT RECORD 



004;> 
004;, 



2000 
2001 
2002 
2003 
2004 



.PAGE "BOOT RECORD" 
*= FMSORG 

THE FOLLOWING BYTES ARE STORED 
ON DISK SECTOR THEY COMPRISE 



62 



ATARI DOS 2.0S 



07e0 00 
eiei 03 



07e2 

0704 
0706 



0007 
4015 
4C1407 



0709 
070A 
070B 
070C 



03 
01 
00 
0115 



07I3E 00 



070F 
0710 
0711 
0712 



00 
00 
7D 
CB07 



2005 
2006 
2007 
2008 

2009 

2010 

2011 

2012 

2013 

2014 

2015 

2016 

2017 

2018 

2019 

2020 

2021 

2022 

2023 

2024 

2025 

2026 

2027 

2028 

2029 

2030 

2031 

2032 

2033 

2034 

2035 



THE BOOT LOAD RECORD 



BFLG 
BRCNT 



.BYTE 
.BYTE 



BLDADR .WORD FMSORG 
BINTADR .WORD DUPINIT 
BCONT JMP XBCONT 



;BOOT FLAG UNUSED=0 
;N0 CONSECTIVE BOOT 

READ 
;B0OT LOAD ADDR 
;INIT ADDR 
;BOOT READ CONT PT 



RECORDS TO 



THE FOLLOWING BYTES ARE SET BY 
■ THE CONSOLE PROCESSOR. THEY ARE 
: ACTED UPON DURING FMS INIT ONLY, 
r THEY ARE PART OF THE BOOT RECORD 
; THUS DEFINING THE DEFAULT 
[INITIALIZATION FARMS 



SABYTE 
DRVBYT 
SAFBFW 
SASA 



.BYTE 3 
.BYTE 01 
.BYTE 
.WORD ENDFMS 



MAX # CONCURRENT OPEN FILES 
DRIVE BITS 

STORAGE ALLOCATION DIR SW 
STORAGE ALLOCATION START ADDR 



THE FOLLOWING CODE READS THE FMS 
AND CONSOLE PROCESSOR (DOS) FROM 
THE DOS. SYS FILE 



DFSFLG .BYTE 

; 00 NO DOS FILE 

; 01 128 BYTE SECTOR 

: 02 256 BYTE SECTOR 

DFLINK .BYTE 0,0 



2036 BLDISP 

2037 DFLADR 

2038 ; 

2039 XBCONT 
00714 AC0E07 2040 



.BYTE 
.WORD 



125 
DFMSDH 



;DOS FLAG 



DISK 
DISK 

;DOS FILE START SECTOR NUMBER 

;DISPL TO SECTOR LINK 
,-ADDR START OF DOS . SYS FILE 



0717 F036 



0719 
071C 
071E 
0721 



AD1207 
8543 
8D0403 
AD1307 
0724 8544 
0726 8D0503 



2041 
2042 
2043 
2044 
2045 
2046 
2047 
2048 
2049 



LDY 
BEQ 

LDA 
STA 
STA 
LDA 
STA 
STA 



DFSFLG 
BFAIL 

DFLADR 

ZBUFP 

DCBBUF 

DFLADR+1 

ZBUFP+1 

DCBBUF+1 



;GET DOS 
;BR IF NO 



FLAG 
DOS . SYS 



MOVE LOAD START ADDR 
TO ZERO PAGE PTR 
AND TO DCB 



BOOT RECORD 







2050 ; 










0729 


AD1007 


2051 


LDA 


DFLINK+1 




;GET 1ST SECTOR # 


072C 


AC0F07 


2052 


LDY 


DFLINK 






072P 


18 


2053 XBCl 


CLC 








0730 


AE0E07 


2054 


LDX 


DFSFLG 




;LOAD DISK TYPE COl 


0733 


206C07 


2055 


JSR 


BSIO 




;G0 READ BOOT SECT( 


0736 


3017 


2056 
2057 ; 


BMI 


BFAIL 






07 38 


AC1107 


2058 


LDY 


BLDISP 




; POINT TO LINK 


07 3B 


B143 


2059 


LDA 


(ZBUFP) 


Y 


;GET LINK HI 


07 3D 


2903 


2060 


AND 


#LMASK 




;MASK TO LINK BITS 


0'i3F 


48 


2061 


PHA 








0740 


C8 


2062 


INY 








0741 


1143 


2063 


ORA 


(ZBUFP) 


Y 




0T43 


F00E 


2064 


BEQ 


BGOOD 






0745 


B143 


2065 


LDA 


(ZBUFP) 


Y 


;GET LINK LOW 


0747 


A8 


2066 


TAY 









63 



ATARI DOS 2.0S 



074H 205707 

07411 68 
074C 4C2F07 

0741' A9C0 
0751 D001 

0753 68 

0754 0A 

0755 A8 
07 56 60 



0757 
075EI 
075;. 
075D 
0760 
076:: 
076A 
0766 
076!i 
07611 



18 

A543 

6D1107 

8D0403 

8543 

A544 

6900 

8D0503 

8544 

60 



SECTOR I/O 
076C 



076C 

076C 8D0B03 

076F 8C0A03 

0772 A952 

0774 A040 

0776 9004 

0778 A950 

077A A080 



077C 8D0203 
077F 8C0303 

0782 A931 
0784 A00F 



0786 8D0003 
0789 8C0603 

078C A903 
078E 8DFP12 

0791 A900 
0793 A080 

0795 CA 

0796 F004 

0798 A901 
079A A000 

079C 8D0903 



2067 
2068 ; 
2069 
2070 

2071 ; 

2072 BFAIL 
2073 

2074 ; 

2075 BGOOD 

2076 ; 

2077 XBRTN 
2078 

2079 

2080 ; 

2081 INCBA 
2082 

2083 
2084 
2085 
2086 
2087 
2088 
2089 
2090 
2091 ; 



JSR INCBA 



PLA 
JMP 

LDA 
BNE 

PLA 

ASL 
TAY 
RTS 

CLC 
LDA 
ADC 
STA 
STA 
LDA 
ADC 
STA 
STA 
RTS 



XBCl 

#5C0 
XBRTN 



ZBUFP 

BLDISP 

DCBBUF 

ZBUFP 

ZBUFP+1 

#0 

DCBBUF+1 

ZBUFP+1 



;G0 INCREMENT BUF ADR 

; RESTORE LINK HI 
;G0 READ NEXT SECTOR 

;SET FOR CARRY SET 
;ANY P,Y = $80 

;SET FOR CARRY CLEAR 



rlNC BUFFER PTR 
;BY DATA LINK (125) 



2092 
2093 
2094 
2095 
2096 
2097 
2098 
2099 
2100 
2101 
2102 
2103 
2104 
2105 
2106 
2107 
2108 
2109 
2110 
2111 
2112 
2113 
2114 
2115 
2116 
2117 
2118 
2119 
2120 
2121 
2122 
2123 
2124 
2125 
2126 
2127 
2128 
2129 
2130 



.PAGE "SECTOR I/O" 
; BSIO - DO SECTOR I/O 
BSIO = * 



STA 
STY 



DCBSEC+1 
DCBSEC 



BSIOR LDA #DCBCRS 

LDY #$40 

BCC DSIOl 

LDA #DCBCWS 

LDY #$80 



DSIOl 



DSI02 



STA DCBCMD 

STY DCBSTA 

LDA #$31 

LDY #TIMOUT 



STA DCBSBI 
STY DCBTO 



; SET SECTOR HI 
; SECTOR LO 

r ASSUME READ SECTOR 
,-AND GET DATA 
;BR IF READ 

;ELSE LOAD WRITE SECTOR 
;AND PUT DATA 



;SET COMMAND 
rAND SIO CMD 

;DISK SERIAL BUS ID 
.•TIMEOUT DEFAULT LOADED 



LDA 
STA 



#3 
RETRY 



LDA 
LDY 
DEX 
BEQ DSI03 



#0 
#$80 



LDA 
LDY 



#1 
#0 



;SET ID 

;SET TIME OUT 

;SET RETRY COUNT 



;ASSUME 128 BYTE 
.•SECTOR DISK 

;S0 BR 

;ELSE IS 256 



DSI03 STA DCBCNT+1 ; SET I/O BYTE CNT 



64 



ATARI DOS 2.0S 



079F 8C0803 


2131 

2132 ; 

2133 DSI04 


STY 


DCBCNT 


07A2 2059E4 


2134 


JSR 


$E459 


07A5 101D 


2135 
2136 ; 


BPL 


DSI05 


07A7 CEFF12 


2137 


DEC 


RETRY 


07AA 3018 


2138 
2139 ; 


BMI 


DSI05 


7AC A240 


2140 


LDX 


#$40 


7AE A952 


2141 


LDA 


#DCBCRS 


07B0 CD0203 


2142 


CMP 


DCBCMD 


SIJCTOR I/O 








07B3 F009 


2143 


BEQ 


STRTYP 


07B5 A921 


2144 


LDA 


#DCBCFD 


07B7 CD0203 


2145 


CMP 


DCBCMD 


07BA F002 


2146 


BEQ 


STRTYP 


07BC A280 


2147 


LDX 


#$80 


07£E 8E0303 


2148 STRTYP 

2149 ; 


STX 


DCBSTA 


07C1 4GA207 


2150 
2151 ; 


JMP 


DSI04 


07C4 AE0113 


2152 DSI05 


LDX 


CURFCB 


07C7 AD0303 


2153 


LDA 


DCBSTA 


07CA 60 


2154 
2155 ; 


RTS 





;CALL SERIAL I/O 

;IF GOOD I/O THEN RTS 

;TST IF ANOTHER RETRY AVAIL 
;N0 THEN RTS WITH ERROR 

DO RETRY-RESET TYPE ACTION 
ASSUME READ-CK IF IS 
IF COMMAND GET SECTOR 



;YES THEN STORE GETSECTOR IN 
;TEST IF FORMAT CMD 
;IT ALSO RECIEVES DATA 
rYES THEN SET AS GET DATA 
;ELSE STORE PUTSECTOR 



; RETRY THE l/O 

; RELOAD CURRENT FCB 

;AND I/O STATUS SET FLAGS 



FILE MANGER ENTRY POINT 



7CB 



07CB AA08 
07CD 140B 
07CF BE0A 
07D1 CB09 
07D3 000B 
07D5 A60B 



07D7 
7E0 



Gi7E0 AD0C07 

CI7E3 8543 

CI7E5 AD0D07 

CI7E8 8544 



2156 
2157 
2158 
2159 
2160 
2161 
2162 
2163 
2164 
2165 
2166 
2167 
2168 
2169 
2170 
2171 
2172 
2173 
2174 
2175 
2176 
2177 
2178 
2179 
2180 
2181 
2182 
2183 
2184 
2185 
2186 
2187 
2188 
2189 
2190 
2191 



.PAGE "FILE MANGER ENTRY POINT" 

; DFMSDH - DISK FILE MANAGEMENT DISK 
; HANDLER ENTRY POINT 

DFMSDH 

.WORD DFMOPN-1 ;OPEN FILE 

.WORD DFMCLS-1 ;CLOSE FILE 

.WORD DFMGET-1 ;GET FILE 

.WORD DFMPUT-1 ; PUT BYTE 

.WORD DFMSTA-1 ; STATUS 

.WORD DFMDDC-1 ;DEVICE DEPENDENT CMD 

INITIALIZATION CODE 

GIVE ROOM FOR BOOT EXPANSION 1 1 1 

*= $7E0 
DINIT = * 

; SET UP DRIVE INFO 

; DRVTBL - 8 BYTES-ONE FOR EACH POSSIBLE DRIVE 

; = NO DRIVE 

r 1 = 128 BYTE SECTOR DRIVE 

r 2 = 256 BYTE SECTOR DRIVE 

; DBUFA(L,H) 8 TWO BYTE ENTRYS THE 

: DRIVE (VTOC) BUFFER ADR FOR A DRIVE 



LDA SASA 

STA ZBUFP 

LDA SASA+1 

STA ZBUFP+1 



.-MOVE START OF ALLOC 
;AREA TO ZBUFP 



65 



ATARI DOS 2.0S 



07E* 
07Er' 



AD0A07 
8D0C13 



07Fe A207 



07F2 
07F5 
07FE 

07F* 
07FC 
07FF 
0802 
0805 



8E0D13 
0E0C13 
B00D 

A900 

9D1113 

9D2913 

9D3113 

F036 



2192 
2193 
2194 ; 
2195 

2196 ; 

2197 DIA 
2198 
2199 
2200 ; 
2201 
2202 
2203 
2204 
2205 
2206 ; 



LDA 
STA 



STX 
ASL 
BCS 

LDA 
STA 
STA 
STA 
BEQ 



DRVBYT 
TEMPI 



LDX #7 



TEMP2 
TEMPI 
DIHAVE 

*0 

DRVTBL.X 

DBUFAL.X 

DBUFAH.X 

DIDDEC 



;TEMP 1 IS DRIVE 

; EXCESS BITS FROM BOOT 

;TEMP 2 IS 

;DR # MINUS 1 

; SHIFT DR BIT TO CARRY 

;BR IF DR EXISTS 

DRVTBL.X ;SET NO DRIVE 



;G0 DEC DRIVE # 



FILE MANGER ENTRY POINT 



0807 A005 
0809 A900 
080B 9143 

080D E8 
080E 8B0103 
0811 A953 
0813 8D0203 
0816 2053E4 

0819 A002 
081B ADEA02 
081E 2920 

0820 D001 
0822 88 



0823 
0824 
082 7 
082A 
082C 
082F 
0831 
0834 



98 

AE0D13 

9D1113 

A543 

9D2913 

A544 

9D3113 

207008 



0837 88 

0838 F003 



083A 207008 



083D CA 
083E 10B2 



0840 AC0907 
0843 A200 



0845 A900 



2207 
2208 
2209 
2210 
2211 
2212 
2213 
2214 
2215 
2216 
2217 
2218 
2219 
2220 
2221 
2222 
2223 
2224 
2225 
2226 
2227 
2228 
2229 
2230 
2231 
2232 
2233 
2234 
2235 
2236 
2237 
2238 
2239 
2240 
2241 
2242 
2243 
2244 
2245 
2246 
2247 
2248 
2249 
2250 
2251 
2252 
2253 
2254 
2255 



DIHAVE 



LDY #DVDWRQ ; SET WRITE READ OFF 

LDA #0 

STA (ZBUFP),Y ;IN THE DRIVE BUFFER 



;PUT DR # IN DCB 
;GET DRIVE STATUS 



DI256 



INX 




STX 


DCBDRV 


LDA 


#DCBCST 


STA 


DCBCMD 


JSR 


DHADR 


LDY 


#2 


LDA 


$2EA 


AND 


#$20 


BNE 


DI256 


PEY 




TYA 




LDX 


TEMP2 


STA 


DRVTBL.X 


LDA 


ZBUFP 


STA 


DBUFAL.X 


LDA 


ZBUFP+1 


STA 


DBUFAH.X 


JSR 


DINCBP 


DEY 




BEQ 


DIDDEC 



JSR DINCBP 



DIDDEC PEX 

BPL DIA 



.•ASSUME 256 BYTE DRIVE 
;GET STATUS BYTE 



,-BR IF 256 



;SET DR TYPE INTO 
;TBL AT DRIVE DISPL 
;MOVE CURRENT ALLOC 
;ADDR TO DBUFA 
;AND INC ALLOC 
rBY 128 BYTES 
;VIA DINCBP 

;IF DR WAS A 

;128 BYTES THEN DONE 

;ELSE INC PTR BY 128 

;DEC DRIVE 

;BR IF MORE TO TEST 



SET UP SECTOR ALLOCATION TABLE 

THE SECTOR ALLOCATION TABLE (SECTBL) 
WAS 16 ONE BYTE ENTRIES ONE FOR 
EACH POSSIBLE 128 BYTE BUFFER SABYTE 
IN THE BOOT RECORD DETERMINES THE 
NUMBER OF ENTRYS TO ALLOCATE 
NON-ALLOCATED BYTE ARE MINUS 

SABUF(L.H) CONTAINS THE ADDR OF THE SECTOR BUFFER 

;GET AND SAVE COUNT 



LDY SABYTE 
LDX #0 



DINXTS LDA #0 



; ASSUME ALLOCATE 



66 



ATARI DOS 2.0S 



01347 88 2256 

0848 1001 2257 
084A 98 2258 



DEY ;DEC COUNT OF ALLOCATED 

BPL DISETS ;IF PLUS STILL ALLOCATE 
TYA ;ELSE DE ALLOCATE 



FILE MANGER ENTRY POINT 







2259 


; 








034B 


9D1913 


2260 


DISETS 


STA 


SECTBL.X 


,-SET ALLOCATE BYTE 


0B4E 


98 


2261 




TYA 




;IF NO ALLOCATED 


0B4F 


300D 


2262 
2263 


} 


BMI 


DISNI 


;THEN DON'T ALLOC A' 


0851 


A543 


2264 




LDA 


ZBUFP 


rMOVE BUFFER ADDR 


0B53 


9D3913 


2265 




STA 


SABUFL, X 


;T0 SECTOR BUF PTR 


0856 


A544 


2266 




LDA 


ZBUFP+1 




0858 


9D4913 


2267 




STA 


SABUFH.X 




085B 


207008 


2268 
2269 


, 


JSR 


DINCBP 


!lNC SECTOR ADDR 


085E 


E8 


2270 


DISNI 


INX 




;INC BUF # 


085F 


E010 


2271 




CPX 


#16 


;IF NOT ALL 16 


0861 


D0E2 


2272 
2273 




BNE 


DINXTS 


;D0 AGAIN 






2274 


,- SET : 


LOW MEM 








2275 










0863 


A543 


2276 




LDA 


ZBUFP 


;MOVE FINAL ADDR 


0865 


8DE702 


2277 




STA 


LMADR 


.•TO LOW MEM PTR 


0868 


A544 


2278 




LDA 


ZBUFP+1 




086A 


8DE802 


2279 
2280 


; 


STA 


LMADR+1 




086D 


4C7E08 


2281 
2282 


! 


JMP 


CLRFCB 


;CONT INIT 






2283 


; DINCBP - 


INC ZBUFP 


BY 128 






2284 


; 








e870 


18 


2285 


DINCBP 


CLC 






e871 


A543 


2286 




LDA 


ZBUFP 




e873 


6980 


2287 




ADC 


#128 




e875 


8543 


2288 




STA 


ZBUFP 




8877 


A544 


2289 




LDA 


ZBUFP+1 




8879 


6900 


2290 




ADC 


#0 




e87B 


8544 


2291 




STA 


ZBUFP+1 




e87D 


60 


2292 
2293 


, 


RTS 










2294 


; CLEAR FCBS TO ZERO 








2295 


• 








ei87E 




2296 


CLRFCB 


= 


* 




ei87E 


A07F 


2297 




LDY 


#?7F 


;128 OF FCB 


CI880 


A900 


2298 




LDA 


#0 




(1882 


998113 


2299 


CFCBX 


STA 


FCB.Y 


;T0 BE CLEARED 


0885 


88 


2300 




DEY 






0886 


D0FA 


2301 
2302 


; 


BNE 


CFCBX 




FILE 


MANGER 


ENTRY 


POINT 








0B88 




2303 




.PAGE 








2304 


; 








0888 


A000 


2305 




LDY 


#0 




088A 


B91A03 


2306 


ADIl 


LDA 


DEVTAB.Y 


;FIND AH 


088D 


F00C 


2307 




BEQ 


ADI2 


; UNUSED 


088F 


C944 


2308 




CMP 


#'D 


;0R DISK 


0891 


F008 


2309 




BEQ 


ADI2 


; EMPTY 


0893 


C8 


2310 




INY 






0894 


C8 


2311 




INY 






0895 


C8 


2312 




INY 






0896 


C01E 


2313 




CPY 


#30 




0898 


D0F0 


2314 




BNE 


ADIl 




089A 


00 


2315 
2316 


; 


BRK 




;ELSE BREAK 



67 



ATARI DOS 2.0S 



089B A944 



2317 ADI2 LDA #'D 



089D ')91A03 2318 
08A0 A9CB 2319 
08A2 991B03 2320 
08A5 A907 2321 
08A7 991C03 2322 
2323 
08AA i50 2324 



STA 
LDA 
STA 
LDA 
STA 

RTS 



;SET DISK 



DEVTAB , Y 
#DFMSDHS,2 55 
DEVTAB+1,Y 
#DFMSDH/2 56 
DEVTAB+2 , y 



rSET FMS ADDR 



OPEN 



08AB 




2325 




.PAGE "OPEN" 








2326 


; 












2327 


1 DFMOPN - 


FILE OPEN 


EXECUTION ENTRY PT 






2328 


; 












2329 


DFMOPN 








08AB 


206411 


2330 




JSR 


SETUP 


; DO FOB SET UP 


08AE 


209E0E 


2331 




JSR 


FNDCODE 


;G0 DECODE FILE NAME 


08B1 


BD4A03 


2332 




LDA 


ICAUXl , X 


; GET AUXl (OPEN TYPE CODES) 


08B4 


9D8213 


2333 




STA 


FCBOTC.X 


;PUT INTO FCB 


08B7 


2902 


2334 




AND 


#OPDIR 


; IS THIS LIST DIRECTORY 


08B9 


F003 


2335 




BEQ 


OPNl 


;BR IF NOT 


08BB 


4CAD0D 


2336 
2337 


. 


JMP 


LISTDIR 


;GOT0 DIR LIST CODE 


08BE 


20210F 


2338 


OPNl 


JSR 


SPDIR 


;GO SEARCH FILE DIR 


08C1 


08 


2339 
2340 


. 


PHP 






08C2 


BD8213 


2341 




LDA 


FCBOTC.X 


;GET OPEN TYPE CODE 


08C5 


C904 


2342 




CMP 


#OPIN 


; INPUT 


08C7 


F00F 


2343 




BEQ 


DFOIN 




08C9 


C908 


2344 




CMP 


#OPOUT 


r OUTPUT 


08CB 


F044 


2345 




BEQ 


DFOOUT 




08CD 


C90C 


2346 




CMP 


#OPIN+OPOUT ; UPDATE 


08CF 


F00C 


2347 




BEQ 


DFOUPD 




08D1 


C909 


2348 




CMP 


♦OPOUT+OPAPND ; APPEND 


08D3 


F017 


2349 




BEQ 


DFOAPN 




08D5 


4CBF12 


2350 
2351 


. 


JMP 


ERDVDC 


TERROR 






2352 


; DFOIN - OPEN FOR INPUT 






2353 


; 








08D8 




2354 


DFOIN 


= 


* 




08D8 


28 


2355 




PLP 




;GET SEARCH FLAG 


08D9 


B00E 


2356 




BCS 


OPNERl 


; ERROR IP NOT FOUND 


08DB 


9006 


2357 
2358 


, 


BCC 


DFOUI 








2359 


; DFOUPD - 


OPEN FOR UPDATA 






2360 


; 








08DD 




2361 


DFOUPD 


= 


* 




08DD 


28 


2362 




PLP 




;GET SEARCH FLAG 


08DE 


B009 


2363 




BCS 


OPNERl 


rBR NOT FOUND 


08E0 


20AC0C 


2364 
2365 


. 


JSR 


TSTLOCK 


;TEST LOCK 


08E3 




2366 


DFOUI 


= 


* 




08E3 


20AE09 


2367 




JSR 


DFRDSU 


;SET UP FOR READ 


08Ee 


4CF012 


2368 
2369 


. 


JMP 


GREAT 


rDONE 


08E9 


4CBB12 


2370 


OPNERl 


JMP 


ERFNF 


;FILE NOT FOUND 


OPEN 


f 












08EC 




2371 




.PAGE 








2372 


; 












2373 


; DFOAPN - 


OPEN APPEND 






2374 


• 








08EC 




2375 


DFOAPN = 


* 




08EC 


: 28 


2376 




PLP 




;GET READ STATUS 



68 



ATARI DOS 2.0S 



0(iED 
0(!EF 
0HF2 
0HF5 
0HF7 
0f)F9 
0HFC 
0f!FF 
0902 
0905 
0908 
090B 
090E 



B0FA 

AC0513 

B90114 

2902 

F015 

20AC0C 

20BF10 

200611 

9D8E13 

BD8B13 

9D8D13 

4C7C09 

4CB712 



0911 

0911 28 

0912 B009 

0914 20530C 
0917 AC0513 
091A 4C4809 

09 ID 

091D AD0213 
0920 3070 
0922 8D0613 



0925 
0928 
092B 
09 2 E 
0931 
0934 
0937 
093A 
093C 
093E 



206E10 

AD0313 

8D0513 

AD0413 

8D0713 

20BF10 

AC0513 

A20A 

A920 

990614 



0'>41 C8 

0942 CA 

0943 10F9 
0945 AE0113 

0948 

0948 200611 



2377 
2378 
2379 
2380 
2381 
2382 
2383 
2384 
2385 
2386 
2387 
2388 
2389 
2390 
2391 
2392 
2393 
2394 
2395 
2396 
2397 
2398 
2399 
2400 
2401 
2402 
2403 
2404 

2405 
2406 
2407 
2408 
2409 
2410 
2411 
2412 
2413 



BCS 
LDY 
LDA 
AND 
BEQ 
JSR 
JSR 
JSR 
STA 
LDA 
STA 
JMP 
APOER JMP 



OPNERl ;BR NOT FOUND 
CDIRD ;IF OLD. 
FILDIR+DFDFLl,y ;FILE TYPE 



#DFDNLD 

APOER ; 

TSTLOCK 1 

OPVTOC ; 

GETSECTOR i 
FCBSSN+1,X 

FCBLSN.X ; 
FCBSSN.X 

DHF0X2 ) 
ERAPO 



THEN 

ERROR 

TEST LOCKED 

READ VTOC 

GET A SECTOR 

;MOVE START SECTOR 

TO START SECTOR # 

CONTINUE AS OPEN 



DFOOUT - OPEN FOR OUTPUT 



DFOOUT = 

PLP 
BCS 

JSR 

LDY 
JMP 



DFOXl 



LDA 
BMI 
STA 

JSR 
LDA 
STA 
LDA 
STA 
JSR 
LDY 
LDX 
LDA 



2414 OPNIB STA 



2415 
2416 
2417 
2418 

2419 ; 

2420 OPNIA = 

2421 JSR 



INY 
DEX 
BPL 
LDX 



DFOXl 

XDEL0 
CDIRD 
OPNIA 



DHOLES 
0PNER2 
CDIRS 



RDDIR 

DHOLED 

CDIRD 

DHFNUM 

SFNUM 

OPVTOC 

CDIRD 

#10 

#$20 

FILDIR+DFDPFN.Y 



OPNIB 
CURFCB 



rGET SEARCH FLAG 



; DELETE THE FILE OR FILES 



;WAS THERE A HOLE 

;BR IF NO HOLE 

rSAVE HOLE SECTOR AS CURRENT 

DIR SEC 
;G0 READ CURRENT DIR SECTOR 
jMOVE HOLE DISPL TO 
;CUR DIR DISPL 
;MOVE HOLE FN 
;T0 CURRENT 



jBLANK FILL FILE ENTRY 
FOR FILE NAME 



GETSECTOR ;GET A SECTOR 



OPEN 



094B 


AC0513 


2422 


LDY 


034E 


990514 


2423 


STA 


0951 


BD8B13 


2424 


LDA 


0954 


990414 


2425 
2426 ; 


STA 


0957 


A943 


2427 


LDA 


0959 


990114 


2428 


STA 


095C 


A900 


2429 


LDA 


095E 


990314 


2430 


STA 


0')61 


990214 


2431 
2432 ; 


STA 


0964 


A200 


2433 


LDX 


0!)66 


BD5913 


2434 0PN2 


LDA 


0969 


C93F 


2435 


CMP 


096B 


F003 


2436 


BEQ 



CDIRD ;GET DIR DISPL 
FILDIR+DFDSSN+1,Y ; PUT SECTOR INTO DIR 

REC 
FCBLSN.X 
FILDIR+DFDSSN.Y 

#DFDINU+DFDOUT+DFDNLD ;SET DIR ENTRY IN 

USE 
FILDIR+DFDFL1,Y 
#0 ; SET NOT LOCKED 
FILDIR+DFDCNT+1,Y ;SET COUNT = 
FILDIR+DFDCNT,Y 

#0 

FNAME,X ;MOVE FILE NAME 

*'? rIF WILD CARD 

0PN2A ; CHANGE TO BLANK 



69 



ATARI DOS 2.0S 



096D 


990614 


2437 




STA 


FILDIR+DFDPFN.Y ;T0 DIRECTORY 


0970 




2438 


0PN2A 


= 


* 




0970 


C8 


2439 




INY 






0971 


E8 


2440 




INX 






0972 


E00B 


2441 




CPX 


#11 




0974 


90F0 


2442 
2443 


. 


BCC 


0PN2 




0976 


AE0113 


2444 




LDX 


CURFCB 


; RESTORE X REG 


0979 


207110 


2445 




JSR 


WRTDIR 


;G0 WRITE DIRECTORY 


09 7C 




2446 


DHF0X2 


= 


* 




097C 


209509 


2447 




JSR 


SETFCB 




097F 


20E20F 


2448 




JSR 


WRTN6 


;FIX UP AS IF WRITE 


0982 


A980 


2449 


0PN3 


LDA 


#FCBFAS 


;SET NEW FILE 


0984 


9D8513 


2450 




STA 


FCBFLG.X 




0987 


209B12 


2451 




JSR 


TSTDOS 


rIF NOT DOS 


098A 


D003 


2452 




BNE 


DHF0X3 


rBR 


098C 


4C0A12 


2453 




JMP 


WRTDOS 


;ELSE DO IT 


098F 




2454 


DHF0X3 


= 


* 




098F 


4CF012 


2455 
2456 


, 


JMP 


GREAT 




0992 


20BD12 


2457 
2458 
2459 


0PNER2 


JSR 


ERDFULL 


.•DIRECTORY FULL 


0995 




2460 


SETFCB 


= 


* 




0995 


A900 


2461 




LDA 


#0 


; CLEAR 


0997 


9D8513 


2462 




STA 


FCBFLG.X 


;FLAG 


099A 


AD0713 


2463 


OPNFl 


LDA 


SPNUM 


;MOVE FILE NUM TO FCB 


099D 


0A 


2464 




ASL 


A 




099E 


0A 


2465 




ASL 


A 




099F 


9D8113 


2466 




STA 


FCBFNO.X 




09A2 


A900 


2467 




LDA 


*0 




09A4 


9D8713 


2468 




STA 


FCBDLN.X 


;DATA LENGTH 


09A7 


9D8F13 


2469 




STA 


FCBCNT.X 


;SET CNT = 


09AA 


9D9013 


2470 




STA 


FCBCNT+1 , 


X 


09AD 


60 


2471 




RTS 






09AE 


209509 


2472 


DFRDSU 


JSR 


SETFCB 


,-SET UP FCB 


09B1 


AC0513 


2473 




LDY 


CDIRD 


;MOVE START SECTOR TO LINK 


OPEN 














09B4 


B90114 


2474 




LDA 


DFDFLl+FILDIR.Y ;SET NEW 


09B7 


2902 


2475 




AND 


♦DFDNLD 


; SECTOR 


09B9 


9D8413 


2476 




STA 


FCBSLT.X 


;FLAG 


09BC 


B90414 


2477 




LDA 


FILDIR+DFDSSN.Y 


09BF 


9D8B13 


2478 




STA 


FCBLSN.X 




09C2 


B90514 


2479 




LDA 


FILDIR+DFDSSN+1 . Y 


09C5 


9D8C13 


2480 




STA 


FCBLSN+1 , 


X 


09C8 


201710 


2481 




JSR 


RDNSO 


;READ 1ST SECTOR 


09CB 


60 


2482 




RTS 






09CC 




25 




.INCLUDE #E! 




09CC 




30 




.INCLUDE #DiATFMS2.SRC 


PUT EIYTE 












09CC 




3000 




.PAGE "PUT BYTE" 






3001 














3002 


r DFMPUT - 


PUT A FILE 


BYTE 






3003 














3004 


DFMPUT 








09CC 


8D0813 


3005 




STA 


SVDBYT 




09CF 


BD4103 


3006 




LDA 


ICDNO.X 




09D2 


8521 


3007 




STA 


ICDNO-IOCB+ZICB 


09D4 


206411 


3008 




JSR 


SETUP 




09D7 


AC0013 


3009 




LDY 


ENTSTK 


;CHK TO SEE IF ENTRY WASN'T 
FROM CIO 


09DA 


B90201 


3010 




LDA 


STAK.Y 


;IF HI BYTE RTS IS NOT IN OS 
ADDR 



70 



ATARI DOS 2.0S 



09I)D C9DF 3011 
09I)F B004 3012 
09I!1 A900 3013 



09Ii3 
091! 5 
09i:8 
09I!A 
09I!C 
091!F 
091'0 
09!''3 
09F5 
09)'8 
091-'A 
091?D 
091?F 
0A01 
0AI93 



8522 

BD8213 

2908 

F02D 

BC8713 

98 

DD8613 

9011 

20940F 

B022 

201F0A 

A000 

B005 

B124 

8D0813 



0AI36 FE8713 
0A09 AD0813 
0Ai3C 9147 

0AI2IE A940 
0A10 1D8513 
0A13 9D8513 

0A16 4CF012 

0A19 4CBF12 
0AIC 4CF412 



3014 

3015 FRMCIO 

3016 

3017 

3018 

3019 

3020 

3021 

3022 

3023 

3024 

3025 

3026 

3027 

302B 

3029 ; 

3030 PUTl 
3031 
3032 
3033 ; 
3034 
3035 
3036 
3037 ; 
3038 

3039 ; 

3040 PUTER 

3041 PEOF 



CMP 
BCS 
LDA 

STA 
LDA 
AND 
BEQ 
LDY 
TYA 
CMP 
BCC 
JSR 
BCS 
JSR 
LDY 
BCS 
LDA 
STA 

INC 
LDA 
STA 

LDA 
ORA 

STA 



#OSBTM ; SPACE THEN A NON-CIO ENTRY 

FRMCIO ;BR IF FROM CIO 

#0 ;ELSE PREVENT FROM DOING BURST 

I/O 
ICCOMZ 

FCBOTC.X ;IF NOT OPEN 

#OPOUT ; OUTPUT 

PUTER ; ERROR 

FCBDLN.X ;GET DATA LENGTH 

FCBMLN.X ;IF SECTOR NOT FULL 

PUTl ;THEN BR 

WRTNXS ;ELSE WRITE FULL SECTOR 

PEOF ;BR IF EOF 

WTBUR rTEST BURST 

#0 

PUTl ;BR IF NOT BURST 

(ICBALZ),Y ;PUT NEXT BYTE 

SVDBYT rAFTER BURST AREA 

FCBDLN.X ;INC DATA LEN 

SVDBYT ;GET DATA BYTE 

(ZSBA),Y ;AND PUT IN SECTOR BUFFER 



#FCBFSM 

FCBFLG.X 

FCBFLG.X 



! INDICATE SECTOR MODIFIED 



JMP GREAT 



JMP 
JMP 



ERDVDC 
ERREOF 



BURST I/O 
0A1F 



0S1F BD8513 
0A22 1026 
0A24 3002 

0;>26 A900 

0?.28 8D1013 
0?.2B A522 
0;i.2D 2902 
0?.2F F019 

0;31 20AE0A 
0J.34 B014 

0;l36 A524 
0A38 8547 
0;l3A A525 
0;l3C 8548 

0A3E AD1013 
0A41 3009 

0A43 200F10 
0A46 9033 
0A48 B053 

0iUA 38 
0iUB 60 



3042 
3043 
3044 
3045 
3046 
3047 
3048 
3049 
3050 
3051 
3052 
3053 
3054 
3055 
3056 
3057 
3058 
3059 
3060 
3061 
3062 
3063 
3064 
3065 
3066 
3067 
3068 
3069 
3070 
3071 
3072 
3073 



.PAGE "BURST I/O" 
; TEST BURST l/O AND DO IF POSSIBLE 
WTBUR 



LDA 
BPL 
BMI 



FCBFLG.X 

NOBURST 

TBURST 



RTBUR LDA #0 

TBURST STA BURTYP 

LDA ICCOMZ 

AND #2 

BEO NOBURST 

JSR TBLEN 

BCS NOBURST 

LDA ICBALZ 

STA ZSBA 

LDA ICBAHZ 

STA ZSBA+1 

NXTBUR LDA BURTYP 

BMI WRBUR 

JSR RDNXTS 

BCC BBINC 

BCS BUREOF 

NOBURST SEC 
RTS 



;IF NOT AQUIRING SECTORS 
.-THEN UPDATE AND 
;NO BURST 

rSET READ TYPE 

•SET BURST TYPE 
;IF CMD 
;IS TEXT MODE 
;THEN NO BURST 

;IF USER BUFFER LESS 
;THEN SECTOR, NO BURST 

;MOVE USER BUFFER 
;ADDR TO SECTPOR 
; BUFFER PTR 



;GET I/O TYPE 
;BR IF WRITE 

J DO SECTOR READ 
;BR IF EOF 
;BR RD EOF 

; INDICATE NO BURST 



71 



AT/iRI DOS 2.0S 







3074 ; 










0A4C 


ADF812 


3075 WRBUR 


LDA 


DRVMDL 




;WRITE FULL SECTOR 


0A4F 


9D8713 


3076 
3077 ; 


STA 


FCBDLN, 


X 


;DATA COUNT 


0A52 


A8 


3078 


TAY 








0A53 


B147 


3079 


LDA 


(ZSBA), 


Y 


rSAVE DATA TO BE 


0A55 


8D0913 


3080 


STA 


SVDl 




;T0 BE CLOBBERED 


0A58 


C8 


3081 


INY 








0A59 


B147 


3082 


LDA 


(ZSBA), 


Y 


;BY WRTNXT 


0A5B 


8D0A13 


3083 


STA 


SVD2 






0A5E 


C8 


3084 


INY 








0A5F 


B147 


3085 


LDA 


(ZSBA), 


Y 




0A61 


8D0B13 


3086 
3087 ; 


STA 


SVD3 






0A64 


20940F 


3088 
3089 ; 


JSR 


WRTNXS 




;WRITE SECTOR 


0A67 


ACF812 


3090 


LDY 


DRVMDL 




; RESTORE CLOBBERED DAI 


0AeA 


AD0913 


3091 


LDA 


SVDl 






0A6D 


9147 


3092 


STA 


(ZSBA), 


Y 




BURST I/O 












0A6F 


C8 


3093 


INY 








0A70 


AD0A13 


3094 


LDA 


SVD2 






0A73 


9147 


3095 


STA 


(ZSBA) 


Y 




0A75 


C8 


3096 


INY 








0A76 


AD0B13 


3097 


LDA 


SVD3 






0A79 


9147 


3098 

3099 ; 

3100 ; 


STA 


(ZSBA) 


Y 




0A7B 


18 


3101 BBINC 


CLC 








0A7C 


A547 


3102 


LDA 


ZSBA 




;INC SECTOR 


0A7E 


7D8613 


3103 


ADC 


FCBMLN 


X 


; BUFFER ADDR BY 


0A81 


8547 


3104 


STA 


ZSBA 




; ACTUAL DATA LEN 


0A83 


A548 


3105 


LDA 


ZSBA+1 




;GOT OT PUT 


0A85 


6900 


3106 


ADC 


#0 






0A87 


8548 


3107 
3108 ; 


STA 


ZSBA+1 






0A89 


38 


3109 


SEC 








0A8A 


A528 


3110 


LDA 


ICBLLZ 




;DEC USER 


0A8C 


FD8613 


3111 


SBC 


FCBMLN 


X 


; BUFFER LEN BY 


0A8F 


8528 


3112 


STA 


ICBLLZ 




; ACTUAL DATA LEN 


0A91 


A529 


3113 


LDA 


ICBLHZ 




;GOT OR PUT 


0A93 


E900 


3114 


SBC 


#0 






0A95 


EA 


3115 


NOP 








0A96 


8529 


3116 
3117 ; 


STA 


ICBLHZ 






0A98 


20AE0A 


3118 


JSR 


TBLEN 




,-IF USER BUF LEN 


0A9B 


90A1 


3119 
3120 ; 


BCC 


NXTBUR 




;NOW >= SECTOR, DO AG 


0A9D 




3121 BUREOF 


= 


* 




;END OF BURSTING 


0A9D 


A547 


3122 


LDA 


ZSBA 




;MOVE FINAL ADDR BACK 


0A9F 


8524 


3123 


STA 


ICBALZ 




;T0 USER BUF PTR 


0AA1 


A548 


3124 


LDA 


ZSBA+1 






0AA3 


8525 


3125 
3126 ; 


STA 


ICBAHZ 






0AA5 


BC8813 


3127 


LDY 


FCBBUF 


X 


; RESTORE ZSBA 


0AA8 


88 


3128 


DEY 








0AA9 


20D011 


3129 
3130 ; 


JSR 


SSBA 






0AAC 


18 


3131 BURST 


CLC 








0AAD 


60 


3132 
3133 ; 


RTS 












3134 ,- TEST 


USER 


BUF LEN FOR BURST 






3135 ; 










0AAE 




3136 TBLEN 


= . 


* 






0AAE 


ADFE12 


3137 


LDA 


DRVTYP 




;IF DRIVE NOT 



72 



ATARI DOS 2.0S 



0AE1 


C901 


3138 




CMP 


#1 


;128 BYTE SECTOR TYPE 


0AEi3 


D004 


3139 
3140 ! 




BNE 


TBL256 


;THEN DO 256 BYTE TEST 


0AE;5 


A528 


3141 




LDA 


ICBLLZ 




0AEi7 


30F3 


3142 
3143 




BMI 


BURST 




0AEI9 


A529 


3144 TBL256 


LDA 


ICBLHZ 


;IF BUF LEN HI >= 256 


BUBST 


I/O 












0AEB 


D0EF 


3145 




BNE 


BURST 


;THEN CAN BURST 


0AE;D 


38 


3146 




SEC 






0AE:E 


60 


3147 




RTS 






GET BYTE 












0AI1F 




3148 




.PAGE "GET BYTE" 






3149 














3150 














3151 


DFMGET - 


SET A FILE 


BYTE 






3152 










0AI1F 




3153 I 


3FMGET 


= 


* 




0ABF 


206411 


3154 




JSR 


SETUP 


;G0 SET UP 


0AC;2 


BD8213 


3155 




LDA 


FCBOTCX 


rIF OPEN FOR 


0A<;5 


2902 


3156 




AND 


#OPDIR 


;DIR CNT 


0A<;7 


F003 


3157 




BEQ 


GETl 




0A(;9 


4CB90D 


3158 
3159 




JMP 


GDCHAR 


;THEN GO TO DIR RTN 


0A(:c 


BD8713 


3160 


3ET1 


LDA 


FCBDLN.X 


;GET DATA LEN 


0a(:f 


DD8613 


3161 




CMP 


FCBMLN.X 


;TEST EMPTY SECTOR 


0A132 


900B 


3162 




BCC 


GET 2 


;BR IF NOT EMPTY 


0A154 


20260A 


3163 




JSR 


RTBUR 


;D0 BURST IF POSSIBLE 


0A1)7 


200F10 


3164 




JSR 


RDNXTS 


;GET NEXT SECTOR 


0A1)A 


90F0 


3165 




BCC 


GETl 


;BR IF NOT EOF 


0A1X: 




3166 


3E0F 


=; 


* 




0A1X; 


4CF412 


3167 
3168 


• 


JMP 


ERREOF 


;ELSE EOF ERROR 


0ADF 


A8 


3169 


SET2 


TAY 






0AK0 


B147 


3170 




LDA 


(ZSBA),Y 


;GET DATA BYTE 


0a:52 


8D0813 


3171 




STA 


SVDBYT 


rSAVE THE BYTE 


0a:35 


C8 


3172 




INY 






0A:Ee 


98 


3173 




TYA 






0a:e7 


9D8713 


3174 




STA 


FCBDLN.X 


;AND SET NEW VALUE 


0AEA 




3175 


EFLOOK 


= 


* 




0AEA 


BC8B13 


3176 




LDY 


FCBLSN.X 


;D0 EOF LOOK AHEAD 


0AED 


D00F 


3177 




BNE 


GET 3 


;IF LSN NOT ZERO 


0AEF 


BC8C13 


3178 




LDY 


FCBLSN+1 , 


X ;THEN 


0AF2 


D00A 


3179 




BNE 


GET 3 


;NOT EOF 


0AF4 


DD8613 


3180 




CMP 


FCBMLN.X 


;IF LSN=0 THEN CHECK F 


0AF7 


9005 


3181 




BCC 


GET 3 


;LAST BYTE 


0AF9 


A903 


3182 




LDA 


#503 


;IF LAST BYTE THEN RTS 


00\FB 4CD312 3183 




JMF 


RETURN 








3184 


; 








0AFE 


4CF012 


3185 


GET3 


JMP 


GREAT 




STATUS 













0B01 




3186 




.PAGE "STATU 






3187 


; 










3188 


; DFMSTA - 


GET A FI 






3189 


; 










3190 


DFMSTA 






01301 


206411 


3191 




JSR 


SETUP 


01304 


209E0E 


3192 




JSR 


FNDCODE 


01307 


20210F 


3193 




JSR 


SFDIR 


0130A 


B006 


3194 




BCS 


SFNF 



FILE STATUS 



; SETUP 

; DECODE FILE NAME 
; SEARCH FOR FILE 
;BR NOT FOUND 



73 



ATARI DOS 2.0S 



0B0C 


20AC0C 


3195 




JSR 


TSTLOCK 


0B0F 


4CF012 


3196 
3197 


, 


JMP 


GREAT 


0B12 


4CBB12 


3198 


SFNF 


JMP 


ERFNF 



;TEST LOCKED 

;FILE EXISTS AND UNLOCKED 



close; 



0B15 



0B15 206411 
0B18 Bn8213 
0B1B 2908 
0B1D F04E 

0B1F 3E8513 
0B22 9051 

0B24 20AB0F 

0B27 20800B 
0B2A BD9013 
0B2D 48 
0B2E BD8F13 
0B31 48 

0B32 BD8213 
0B35 2901 
0B37 F017 

0B39 20AE09 
0B3C 200F10 
0B3F 90FB 

0B41 BD8D13 
0B44 9D8B13 
0B47 BD8E13 
0B4A 9D8C13 
0B4D 20B30F 

0B50 AC0513 
0B53 18 
0B54 68 
0B55 790214 
0B58 990214 
0B5B 68 
0B5C 790314 
0B5F 990314 

0B62 A942 
0B64 990114 
0B67 207110 
0B6A 209510 

0B6D A900 
0B6F 9D8213 



3199 
3200 
3201 
3202 
3203 
3204 
3205 
3206 
3207 
3208 
3209 
3210 
3211 
3212 
3213 
3214 
3215 
3216 
3217 
3218 
3219 
3220 
3221 
3222 
3223 
3224 
3225 
3226 
3227 
3228 
3229 
3230 
3231 
3232 
3233 
3234 
3235 
3236 
3237 
3238 
3239 
3240 
3241 
3242 
3243 
3244 
3245 
3246 
3247 
3248 
3249 



.PAGE "CLOSE" 



DFMCLOSE 



CLOSE A FILE 



DFMCLS 



JSR 
LDA 
AND 
BEO 

ROL 
BCC 



APPl 



CLOUT 



LDA 
STA 
LDA 
STA 
JSR 

LDY 
CLC 
PLA 
ADC 
STA 
PLA 
ADC 
STA 

LDA 
STA 
JSR 
JSR 



CLDONE LDA 
STA 



SETUP 
FCBOTCX 
#OPOUT 
CLDONE 

FCBFLG.X 
CLUPDT 



;GET OPEN CODE 
;IF NOT OUTPUT 
;THEN DONE 

;IF NOT ACQUIRING SECTORS 
;THEN IS UPDATE 



JSR WRTLSEC 



RRDIR 
FCBCNT+1 , X 



;WRITE LAST SECTOR 

GO GET DIRECTORY 
;GET CNT OF SECTORS 



JSR 

LDA 

PHA 

LDA FCBCNT.X 

PHA 



LDA FCBOTC.X ;GET OPEN CODE 
AND #OPAPND ;IF NOT APPEND 
BEQ CLOUT ;BR 



JSR DFRDSU 
JSR RDNXTS 
BCC APPl 



;ELSE SET UP FOR READ 
;READ TO EOF 



FCBSSN.X rMOVE START SECTOR 

FCBLSN.X TO EOF LINK SECTOR 

FCBSSN+1,X 

FCBLSN+1,X 

WRTN2 ;THEN WRITE AS NOT EOF 



CDIRD 



;GET DIR DISPL 



FILDIR+DFDCNT.Y 
FILDIR+DFDCNT.Y 

FILDIR+DFDCNT+l,y 
FILDIR+DFDCNT+1,Y 

#DFDINU+DFDNLD ;SET ENTRY TO IN USE 
FILDIR+DFDFLl.Y 
WRTDIR ;WRITE DIR 
WRTVTOC .-WRITE VTOC 



*0 
FCBOTCX 



; CLEAR OPEN CODE 



CLOSE 

0B72 4CEA12 3250 

3251 ; 
0B75 3252 CLUPDT 
0B75 3E8513 3253 
0B78 90F3 3254 



JMP FGREAT 



ROL 
BCC 



FCBFLG.X 
CLDONE 



;IF SECTOR NOT MODIFIED 
;THEN DONE 



74 



ATARI DOS 2.0S 



0B7A 20F80F 3255 

0B7D 4C6D0B 3256 

3257 



JSR WRCSIO 
JMP CLDONE 



;ELSE WRITE IT 
; THEN DONE 



CLOSE 



0Bf!0 




3258 




.PAGE 






3259 


; 










3260 


; RE-READ DIR RECORD 






3261 


; 






0B(i0 




3262 


RRDIR 


= 


* 


0B(!0 


3D8113 


3263 




LDA 


FCBFNO.X 


0BH3 


4A 


3264 




LSR 


A 


0BB4 


4A 


3265 




LSR 


A 


0Bf)5 


8D0713 


3266 
3267 
3268 


; 


STA 


SFNUM 


0Bf)8 


209B0B 


3269 




JSR 


FNSHFT 


03 »B 


8D0613 


3270 




STA 


CDIRS 


0BBE 


209B0B 


3271 




JSR 


FNSHFT 


0B<»1 


209D0B 


3272 




JSR 


FNSHFl 


0B!>4 


0A 


3273 




ASL 


A 


0B95 


8D0513 


3274 
3275 


; 


STA 


CDIRD 


0B<)8 


4C6E10 


3276 




JMP 


RDDIR 


0BI>B 


A900 


3277 


FNSHFT 


LDA 


#0 


0BI»D 


A003 


3278 


FNSHFl 


LDY 


#3 


0B9F 


1E8113 


3279 


FNSHF2 


ASL 


FCBFNO.X 


03 A 2 


2A 


3280 




ROL 


A 


0BA3 


88 


3281 




DEY 




0BiV4 


D0F9 


3282 




BNE 


FNSHF2 


0Bi\6 


60 


3283 




RTS 





•GET FILE NUMBER 



;SET ACU=FILE NO/64 
;T0 GET DIR SECTOR 
;SET ACU TO REM=16 



;T0 GET DIR DISPL 



; SHIFT 3 BITS OF 
;FILE NO INTO ACU 



DEVICE DEPENDENT COMMAND 



03 A 7 



0BA7 
0B.\A 
0BAD 
0BAF 
03 Bl 
03B3 
0BB5 
03 B6 
0B38 
0BBA 
03 BB 
03 BC 
03 BF 
03 C0 
03C3 
0BC4 



206411 

3D4203 

C9FE 

F025 

C927 

B01E 

38 

E920 

9019 

0A 

A8 

B9C50B 

48 

B9C60B 

48 

60 



03C5 
0BC7 
0BC9 
0BCB 
03CD 
03CF 
0BD1 

0027 



0BD8 
0C31 
0BD2 
0C7B 
0C82 
0C39 
0D02 



3284 
3285 
3286 
3287 
3288 
3289 
3290 
3291 
3292 
3293 
3294 
3295 
3296 
3297 
3298 
3299 
3300 
3301 
3302 
3303 
3304 
3305 
3306 
3307 
3308 
3309 
3310 
3311 
3312 
3313 
3314 
3315 



.PAGE "DEVICE DEPENDENT COMMAND" 



DFMDDC - DEVICE DEPENDENT CMD EXECUTION 



JSR 
LDA 
CMP 
3EQ 
CMP 
3CS 
SEC 
SBC 
BCC 
ASL 
TAY 
LDA 
PHA 
LDA 
PHA 
RTS 



SETUP 

ICCOM.X 

#254 

XFV 

♦MAXDDC 

DVDCER 

#S20 

DVDCER 

A 

DVDCVT.Y 

DVDCVT+1 , Y 



;SET UP FOR EXECUTION 

;GET COMMAND 

;IS IT FORMAT 

;BR IF 

;TEST RANGE 

;BR OUT OF RANGE 

; SUBTRACT BASE OF CMDS 
,-3R OUT OF RANGE 



.-PUSH EXECUTION ADDR 



. D3YTE XRENAME-1 ; 20-RENAME 
. DBYTE XDELETE-1 ;21-DELETE 
. DBYTE DVDCER-1 ; INVALID CMD 
.DBYTE XLOCK-1 ;23-LOCK 
.DBYTE XUNLOCK-1 ; 24-UNLOCK 
. DBYTE XPOINT-1 ;25-POINT 
.DBYTE XNOTE-1 ; 26-NOTE 



MAXDDC 



S27 



;MAX DVDC+1 



75 



ATARI DOS 2.0S 



3316 ; 
0BD3 4CBF12 3317 DVDCER JMP ERDVDC 
0BD6 4C180D 3318 XFV JMP XFORMAT 



; FORMAT VECTOR 



RENAWE 



0BD9 



0BD9 209E0E 
0BDC 8C0D13 
0BDF 20210F 
0BE2 9003 
0BE4 4CBB12 

0BE7 20AC0C 
0BEA 209B12 
0BED D003 
0BEF 201912 



.PAGE "RENAME" 
XRENAME - RENAME A FILE OR FILES 



0BF2 
0BF5 
0BF8 
0BFB 
0BFD 
0C00 
0C03 
0C04 
0C07 
0C08 
0C09 



AC0D13 

20B40E 

209B12 

D00F 

AC0513 

B90514 

48 

B90414 

A8 

68 

205312 



0C0C A200 
0C0E AC0513 

0C11 BD5913 
0C14 C93F 
0C16 F003 
0C18 990614 

0C1B C8 
0C1C E8 
0C1D E00B 
0C1F 90F0 
0C21 AE0113 

0C24 207110 

0C27 209E0E 
0C2A 20310F 
0C2D 90B8 

0C2F 4CEA12 



3319 

3320 

3321 

3322 

3323 XRENAME 

3324 

3325 

3326 

3327 

3328 

3329 ; 

3330 XRNl 
3331 
3332 
3333 

3334 XRNIA 
3335 
3336 
3337 
3338 
3339 
3340 
3341 
3342 
3343 
3344 
3345 

3346 ; 

3347 XRNIB 
3348 
3349 

3350 ; 

3351 XRN2 
3352 
3353 
3354 



JSR 
STY 
JSR 
BCC 

JMP 

JSR 
JSR 
BNE 
JSR 

LDY 
JSR 
JSR 
BNE 
LDY 
LDA 
PHA 
LDA 
TAY 
PLA 
JSR 



LDX 
LDY 



LDA 
CMP 
BEQ 
STA 



3355 
3356 
3357 
3358 
3359 
3360 
3361 
3362 
3363 
3364 
3365 
3366 
3367 



XRN3 



FNDCODE 

TEMP2 

SFDIR 

XRNl 

ERFNF 

TSTLOCK 
TSTDOS 
XRNIA 
DELDOS 

TEMP2 

FNDCNX 

TSTDOS 

XRNIB 

CDIRD 

FILDIR+DFDSSN+1 , Y 

FILDIR+DFDSSN.Y 

;A,Y NEW DOS 



; DECODE FILE NAME 
;SAVE FNAME INDEX 
;GO FINE FILE IN DIR 
;BR IF FOUND 



;TEST LOCK 

; IF NOT DOS 

fTHEN 

; DON'T CHANGE SO 

;GET INDEX FOR END FNl 
;G0 DECODE NEXT FILE NAME 
;IF NOT DOS 
;THEN 



SETDSO 



rGO WRITE SECTOR ZERO 



#0 
CDIRD 

FNAME, X ;MOVE FILE NAME 
#'7 ;FROM FNAME TO DIR ENT 
XRN3 ;BUT DON'T CHANGE WILD CARD 
FILDIR+DFDPFN,Y ;CHARS INDICATED IN 
FNAME 



INY 

INX 

CPX #11 

BCC XRN2 

LDX CURFCB 



JSR WRTDIR 

JSR FNDCODE 

JSR CSFDIR 

BCC XRNl 

JMP FGREAT 



; RESTORE X-REG 

;G0 WRITE CIR DIR RECORD 

;GET OLD FILENAME AGAIN 
;CONTINUE SEARCH OF DIR 
;BR IF FOUND ANOTHER 

fGO TO GOOD ENDING 



.PAGE "DELETE" 



DELETE 

0C32 3368 

3369 ; 

3370 ; XDELETE - DELETE ALL FILENAMES THAT MATCH 

3371 ; 

3372 XDELETE 
0C32 209E0E 3373 JSR 



0C35 20210F 3374 



JSR 



FNDCODE 
SFDIR 



;G0 DECODE FILENAME 

r SEARCH DIR FOR FILENAME 



76 



ATARI DOS 2.0S 



0C38 


B03F 


3375 




BCS 


DFNF 


0C3A 




3376 


XDELX 


= 


* 


0C3A 


20530C 


3377 




JSR 


XDEL0 


0C3D 


209B12 


3378 




JSR 


TSTDOS 


0C40 


D003 


3379 




BNE 


XDELY 


0C42 


201912 


3380 
3381 
3382 


XDELY 


JSR 


DELDOS 


0C45 


207110 


3383 


XDEL3 


JSR 


WRTDIR 


0C48 


20310F 


3384 




JSR 


CSFDIR 


0C4B 


90ED 


3385 




BCC 


XDELX 


0C4D 


209510 


3386 




JSR 


WRTVTCX: 


0C50 


4CEA12 


3387 
3388 


, 


JMP 


FGREAT 


0C53 


20BF10 


3389 
3390 


XDEL0 


JSR 


OPVTOC 


0C56 


AC0513 


3391 


XDELl 


LDY 


CDIRD 


0C59 


20AC0C 


3392 




JSR 


TSTLOCK 


0C5C 


A980 


3393 




LDA 


tDFDEDE 


0C5E 


990114 


3394 
3395 


, 


STA 


FILDIR+DFl 


0C61 


20AE09 


3396 




JSR 


DFRDSU 


0C64 


4C6C0C 


3397 
3398 


. 


JMP 


XDEL2A 


0C67 


200F10 


3399 


XDEL2 


JSR 


RDNXTS 


0C6A 


B006 


3400 




BCS 


XDEL4 


0C6C 




3401 


XDEL2A 


= 


* 


0C6C 


20C510 


3402 




JSR 


FRESECT 


0C6F 


4C670C 


3403 
3404 


. 


JMP 


XDEL2 


0C72 




3405 


XDEL4 


= 


* 


0C72 


A005 


3406 




LDY 


#DVDWRQ 


0C74 


A9FF 


3407 




LDA 


#$FF 


0C76 


9145 


3408 




STA 


(ZDRVA),Y 


0C78 


60 


3409 
3410 


: 


RTS 




0C79 


4CBB12 


3411 


DFNF 


JMP 


ERFNF 



;BR NOT FOUND 



WRITE DIR ENTRY 
LOOK FOR NEXT MATCH 
BR IF FOUND 



;GET DIR DISPL 
;G0 TEST LOCK 
;LOAD DELETED FLAG 
FL1,Y rDELETE FILE 



;READ NEXT SECTOR 



;FREE CURRENT SECTOR 



rTURN ON WRITE REQ ' D 



;FILE NOT FOUND 



UCK AND UNLOCK 



0c:7c 




3412 




.PAGE "LOCK AND 


UNLOCK" 






3413 


• 












3414 


; XLOCK - LOCK A FILE 








3415 


; XUNLOCK - 


UNLOCK A FILE 






3416 














3417 


XLOCK 








0<:7C 


A920 


3418 




LDA 


tDFDLOC 


r SET LOCK 


0<:7E 


8D0F13 


3419 




STA 


TEMP4 




0(:81 


D005 


3420 




BNE 


XLCOM 


•GO TO COMMON 






3421 


XUNLOCK 






0C83 


A900 


3422 




LDA 


#0 


:SET UNLOCK 


0<:85 


8D0F13 


3423 
3424 


, 


STA 


TEMP4 




0(:88 


209E0E 


3425 


XLCOM 


JSR 


FNDCODE 


; DECODE FILE NAME 


0<:8B 


20210F 


3426 




JSR 


SFDIR 


;FIND 1ST MATCH 


0C8E 


9003 


3427 




BCC 


XLCl 


rBR MATCH FOUND 


0(:90 


4CBB12 


3428 
3429 


. 


JMP 


ERFNF 


;BR NOT FOUND 


0(:93 


AC0513 


3430 


XLCl 


LDY 


CDIRD 


;GET CURRENT DISPL 


0C96 


B90114 


3431 




LDA 


FILDIR+DFDFLl.Y ;GET LOCK BYTE 


0(:99 


29DF 


3432 




AND 


#$DF 


rTURN OFF LOCK 


0C9B 


0D0F13 


3433 




ORA 


TEMP4 


;0R IN LOCK/UNLOCK 


0C9E 


990114 


3434 




STA 


FILDIR+DFDFLl.Y rSET NEW LOCK 


0(:ai 


207110 


3435 
3436 


, 


JSR 


WRTDIR 


;G0 WRITE 


0CA4 


20310F 


3437 




JSR 


CSFDIR 


;LOOK FOR NEXT MATCH 


0CA7 


90EA 


3438 




BCC 


XLCl 


;BR FOUND 



77 



ATARI DOS 2.0S 



0CA9 4CEA12 3439 JMP FGREAT ;ELSE DONE 

3440 ; 

3441 ; TSTLOCK - TEST FILE LOCKED 

3442 ; 

3443 TSTLOCK 
0CAC AC0513 3444 LDY 
0CAF B90114 3445 LDA 
0CB2 2920 3446 AND 
0CB4 D001 3447 BNE 
0CB6 60 3448 RTS 

3449 ; 
0CB7 4CC112 3450 TLF JMP ERFLOCK 



CDIRD ;GET DIR DISPL 
FILDIR+DFDFLl.Y ;LOAD LOCK BYTE 
♦DFDLOC ;MASK LOCK BIT 
TLF ;BR IF LOCKED 



POINT 



0CBA 




3451 




.PAGE "POINT" 








3452 


• 












3453 


; XPOINT - 


POINT REQUEST 






3454 


; 












3455 


XPOINT 








0CBA 


BD8513 


3456 




LDA 


FCBFLG,X 


;IF ARQ SECTORS 


0CBD 


3041 


3457 




BMI 


PERRl 


; POINT INVALID 


0CBF 


BD4D03 


3458 




LDA 


ICAUX4,X 


;IF REQUEST IS NOT 


0CC2 


DD8A13 


3459 




CMP 


FCBCSN+1 , 


X ;SAME AS CURRENT 


0CC5 


D008 


3460 




BNE 


XPl 


;THEN BR 


0CC7 


BD4C03 


3461 




LDA 


ICAUX3,X 




0CCA 


DD8913 


3462 




CMP 


FCBCSN.X 




0CCD 


F01E 


3463 
3464 


; 


BEQ 


XP2 


jELSE NO NEED TO CI 


0CCF 


BD8513 


3465 


XPl 


LDA 


FCBFLG.X 


;IF NOT MODIFIED 


0CD2 


F008 


3466 




BEQ 


XPIA 


;BR 


0CD4 


20P80F 


3467 




JSR 


WRCSIO 


;ELSE WRITE IT 


0CD7 


A900 


3468 




LDA 


#0 




0CD9 


9D8513 


3469 




STA 


FCBFLG.X 




0CDC 




3470 


XPIA 


s 


* 




0CDC 


BD4D03 


3471 




LDA 


ICAUX4,X 




0CDF 


9D8C13 


3472 




STA 


FCBLSN+1, 


X 


0CE2 


BD4C03 


3473 




LDA 


ICAUX3,X 




0CE5 


9D8B13 


3474 




STA 


FCBLSN.X 




0CE8 


201710 


3475 




JSR 


RDNSO 


;READ REQ SECTOR 


0CEB 


B00A 


3476 
3477 


. 


BCS 


XPERR 




0CED 


BD4E03 


3478 


XP2 


LDA 


ICAUX5,X 


;TEST REQ DATA LEN 


0CF0 


DD8613 


3479 




CMP 


FCBMLN.X 


;LESS THEN MAX 


0CF3 


9005 


3480 




BCC 


XP3 




0CF5 


F003 


3481 




BEQ 


XP3 




0CF7 




3482 


XPERR 


= 


* 




0CF7 


4CC312 


3483 
3484 


, 


JMP 


ERRPDL 


;IF NOT THEN ERROR 


0CFA 


9D8713 


3485 


XP3 


STA 


FCBDLN.X 


;SET NEW DATA LEN 


0CFD 


4CF012 


3486 
3487 


; 


JMP 


GREAT 




0D00 


4CB912 


3488 


PERRl 


JMP 


ERRPOT 





0D03 



3489 



.PAGE "NOTE" 







3490 


; 












3491 


; XNOTE - EXECUTE NOTE 


REQUEST 






3492 


; 












3493 


XNOTE 








0D03 


BD8713 


3494 




LDA 


FCBDLN.X 


fDATA LENGHT VALUE 


0D06 


9D4E03 


3495 




STA 


ICAUX5,X 


;T0 AUX 2 


0D09 


BD8913 


3496 




LDA 


FCBCSN.X 


;CUR SEC NO (LO) 


0D0C 


9D4C03 


3497 




STA 


ICAUX3.X 


J TO AUX 3 



0D0F BD8A13 3498 



LDA FCBCSN+1. X ;CUR SEC NO (HI) 



78 



ATARI DOS 2.0S 



0D:.2 9D4D03 3499 
0d:.5 4CF012 3500 



STA 
JMP 



ICAUX4,X 
GREAT 



;T0 AUX 4 



P01«1AT 
0D:L8 



3501 



.PAGE "FORMAT" 



3502 ; 

3503 ; XFORMAT 

3504 ; 

3505 XFORMAT 



0D18 
0DIA 
0DLD 
0DLF 
0D22 
0D:24 
00 27 
0D29 
0D2C 
0D2F 
0D31 
0D34 



0d:)7 1019 

0D;)9 C090 

0d:)B D012 

0D:iD 

0D3D A000 

0D:JF B147 

0D41 C9FF 

0D43 D007 

0D45 C8 

0D46 B147 

0D48 C9FF 

0DIA F003 

0DtC 4CB512 

0DtF 4CD312 



0D52 A900 
0D54 A8 
0D55 9145 
0D57 C8 
0D58 10FB 



0D5A 
0D5C 
0D5E 
0D60 
0DS1 
0D63 
0D65 
0D66 
0D67 



A000 

A902 

9145 

C8 

A9C3 

9145 

C8 

ce 

9145 



FORMAT A DISKETTE 



A548 

8D0503 

A547 

8D0403 

A921 

8D0203 

A940 

8D0303 

AEFE12 

A931 

AC4602 

208607 



3506 
3507 
3508 
3509 
3510 
3511 
3512 
3513 
3514 
3515 
3516 
3517 

3518 ; 
3519 
3520 
3521 

3522 ; 

3523 TSTFMT 
3524 

3525 
3526 
3527 
3528 
3529 
3530 
3531 

3532 XFBAD 

3533 ; 

3534 XFERR 

3535 ; 

3536 XF0 
3537 
3538 

3539 XFl 
3540 
3541 
3542 ; 
3543 
3544 
3545 
3546 
3547 
3548 
3549 
3550 
3551 



LDA 
STA 
LDA 
STA 
LDA 
STA 
LDA 
STA 
LDX 
LDA 
LDY 
JSR 



BPL 
CPY 
BNE 



LDY 
LDA 
CMP 
BNE 
INY 
LDA 
CMP 
BEQ 
JMP 



LDA 
TAY 
STA 
INY 
BPL 

LDY 
LDA 
STA 
INY 
LDA 
STA 
INY 
INY 
STA 



ZSBA+1 

DCBBUF+1 

ZSBA 

DCBBUF 

♦DCBCFD 

DCBCMD 

#$40 

DCBSTA 

DRVTYP 

#$31 

DSKTIM 

DSI02 



XF0 

#$90 
XFERR 



#0 

(ZSBA),Y 
#$FF 
XFBAD 

(ZSBA),Y 
#$FF 
XFERR 
ERDBAD 



;MOVE VTOC BUF ADR 
;T0 DCB 



J FORMAT 
;T0 DCB 
;TELL SIO RECIEVING DATA 

;GET DR TYPE 128 OR 256 
jBUS I.D. 

;GET FORMAT TIME OUT VALUE 
;GOTO LOCAL DISK HANDLER THEN 
SIO 

; IF NO ERRORS CONT FORMATING 
;ELSE CK FOR DEVICE DONE ERROR 
;N0, THEN ERROR EXIT 

•ELSE CK FOR BAD SECTOR INFO 
; RETURNED BY CONTROLLER 



;BAD SECTORS RET ERR MSG 



;NOT BAD SEC ERR, REQ ERR EXIT 



JMP RETURN 



;DO ERROR EXIT 



#0 

(ZDRVA),Y 

XFl 

#0 ;SET 

#2 ;TYPE = 2 

(ZDRVA),Y 

#$C3 ;SET MSN AND 
(ZDRVA),Y ;NSA=107=2C3 

(ZDRVA),Y 



FORMAT 

0E69 A902 
0D6B 88 
0D6C 9145 
0E6E C8 
0E6F C8 
0E70 9145 



3552 
3553 
3554 
3555 
3556 
3557 



LDA #$02 

DEY 

STA (ZDRVA),Y 

INY 

INY 

STA (ZDRVA),Y 



79 



ATARI DOS 2.0S 







3558 


; 








0D7:: 


A00A 


3559 




LDY 


#DVDSMP 




0D74 


A9FF 


3560 




LDA 


#$FF 


;SET SECTOR MAP TO 


0D7f, 


9145 


3561 


XF2 


STA 


(ZDRVA),y 


;ALL ONES 


0D7EI 


C8 


3562 




INY 






0D7?i 


C064 


3563 




CPY 


#DVDSMP+90 




0D7E1 


D0F9 


3564 
3565 


, 


BNE 


XF2 




0D7D 


A90F 


3566 




LDA 


#50F 


JDEALOCATE 1ST 4 SECTORS 


0D7F 


A00A 


3567 




LDY 


fDVDSMP 


;FOR BOOT 


0D81 


9145 


3568 
3569 


? 


STA 


(ZDRVA),Y 




0D8;i 


A037 


3570 




LDY 


#DVDSMP+45 


; DEALLOCATE MIDDLE 9 


0D8!. 


A900 


3571 




LDA 


#0 




0D8T 


9145 


3572 




STA 


(ZDRVA),Y 


;FOR 


0D8?' 


C8 


3573 




INY 




jVTOC AND FILE DIR 


0D8;i. 


A97F 


3574 




LDA 


#$7F 




0D8C 


9145 


3575 
3576 


, 


STA 


(ZDRVA),Y 




0D8e: 


209510 


3577 
3578 


, 


JSR 


WRTVTOC 


•WRITE THE VTOC 


0D9] 


A900 


3579 




LDA 


#0 


;0 FILLE DIR SECTORS 


0D9; 


A8 


3580 




TAY 






0D94 


990114 


3 581 


XF3 


STA 


FILDIR.Y 


;USE FILE DIR BUFFER 


0D97 


C8 


3582 




INY 






0D9f: 


10FA 


3583 
3584 


. 


BPL 


XF3 




0D9;i 


A907 


3585 




LDA 


#7 


•WRITE TO ALL 8 DIR SECT 


0D9C 


8D0613 


3586 




STA 


CDIRS 




0091' 


207110 


3587 


XF4 


JSR 


WRTDIR 




0DA2 


CE0613 


3588 




DEC 


CDIRS 




0DAE 


10F8 


3589 
3590 


; 


BPL 


XF4 




0DA- 


201912 


3591 
3592 


; 


JSR 


DELDOS 


•SET NO DOS 


0DAA 


4CEA12 


3593 




JMP 


FGREAT 


•DONE 


LIST 


DIRECTORY 










0DA1D 




3594 




.PAGE "LIST DIRECTORY" 






3595 


! 












3596 


; LISTDIR - 


■ LIST THE DIRECTORY 






3597 


; GDCHAR - 


GET NEXT DIR CHARACTER 






3598 


: THE 


DIRECTORY IS LISTED VIA OPEN 






3599 


; LIST 


DIRECTORY FUNCTION EACH DIR 






3600 


; ENTRY THAT MATCHES THE FILE SPEC 






3601 


; IS CONVERTED TO A PRINTABLE FORMAT 






3602 


; INTO 


A SECTOR BUFFER 


THE GET BYTE 






3603 


; ENTRY IS 


USED TO GET 


THE PRINTABLE 






3604 


; CHARACTERS ONE AT A 


TIME. THE 






3605 


; LAST 


LINE PRINTED IS 


ALWAYS A 






3606 


; COUNT OF 


THE NUMBET 


OF SECTORS IN USE 






3607 


; AND 


THE NUMBER REMAINING AVAILABLE SECTORS 






3608 


; 












3609 


LISTDIR 






0DA1) 


A900 


3610 




LDA 


#0 




0DA]? 


8D0F13 


3611 




STA 


TEMP4 




0db:2 


20210F 


3612 




JSR 


SFDIR 


.•SEARCH FOR A FILE NAME 


0db:5 


902C 


3613 




BCC 


LDENTl 


;BR IF FOUND 


0DB7 


B030 


3614 
3615 
3616 


GDCHAR 


BCS 


LDCNT 


;BR IF NOT FOUND 


0DB9 


2C0F13 


3617 




BIT 


TEMP4 


;TEST FLAG 


0DB<; 


3053 


3618 
3619 


. 


BMI 


LDDONE 


;BR IF ALL DONE 


0DB1? 


AC0F13 


3620 




LDY 


TEMP4 


;GET COUNT OF CHARS SENT 


0dc:l 


B147 


3621 




LDA 


(ZSBA),Y 


;GET NEXT CHAR 



80 



ATARI DOS 2.0S 



0DC3 


8D0813 


3622 




STA 


SVDBYT 


; IN SVDBYT 


BDce 


EE0F13 


3623 




INC 


TEMP4 


;INC COUNT 


0DC9 


C99B 


3624 




CMP 


#EOL 


;TEST IF EOL DONE 


0d<:b 


D009 


3625 




BNE 


GDCRTN 


;BR NOT EOL 


0DCD 


C011 


3626 




CPY 


#17 


rWAS THIS AN ENTRY 


0D(:f 


B008 


3627 




BCS 


LDENT 


;BR IF IT WAS 


0D131 


A980 


3628 




LDA 


#S80 


;ELSE INDICATE END 


0DD3 


8D0F13 


3629 
3630 


. 


STA 


TEMP4 


;IN TEMP4 


0DD6 


4CF012 


3631 
3632 


GDCRTN 


JMP 


GREAT 


;DONE 


0DD9 


A900 


3633 


LDENT 


LDA 


#0 


r CLEAR CHAR COUNTER 


0DDB 


8D0F13 


3634 




STA 


TEMP4 




0DDE 


20310F 


3635 




JSR 


CSFDIR 


r SEARCH FOR NEXT MA' 


0D:51 


B00e 


3636 
3637 


LDENTl 


BCS 


LDCNT 


;BR NO MORE MATCHES 


0D33 


20210E 


3638 




JSR 


FDENT 


; FORMAT ENTRY 


0D136 


4CF012 


3639 
3640 


, 


JMP 


GREAT 


;DONE 


0D]39 


208B10 


3641 


LDCNT 


JSR 


RDVTOC 


;READ VTOC 


0d:3c 


A004 


3642 




LDY 


♦DVDNSA+1 


;GET # SECTOR AVR 


00)! E 


B145 


3643 




LDA 


(ZDRVA),Y 




0d:?0 


48 


3644 




PHA 







LIST DIRECTORY 



0DP1 88 
0DF2 B145 
0DF4 A8 
0DF5 68 

0DF6 20570E 

0DF9 A003 
0DFB A20C 
0DFD BD140E 
0E00 9147 
0E02 C8 
0E03 CA 
0E04 10F7 
0E06 20670E 

0E09 A900 
0E0B 8D0F13 
0E0E 4CEA12 



0E11 4CF412 

0E14 53 

0E15 52 

0E16 4F 

0i;i7 54 

0E;18 43 

0e;19 45 

0i;iA 53 

0b:ib 20 

0B:1C 45 

0b;id 45 

0E1E 52 

0E1F 46 

0e:20 20 

000D 

0i;2i 
0i;21 



3645 

3646 

3647 

3648 

3649 ; 

3650 

3651 ; 

3652 

3653 

3654 MVFSCM 

3655 

3656 

3657 

3658 

3659 

3660 ; 

3661 

3662 

3663 

3664 ; 

3665 LDDONE 
3666 

3667 ; 

3668 FSCM 



DEY 

LDA (ZDRVA),Y 

TAY 

PLA 

JSR CVDX 

LDY #3 

LDX #FSCML-1 

LDA FSCM.X 

STA (ZSBA),Y 

INY 

DEX 

BPL MVFSCM 

JSR CVDY 

LDA #0 

STA TEMP4 

JMP PGREAT 



jAND CONVERT 

;SET EOL 
rPUT IN CUTE 
; MSG 



SET CHAR CNT 



JMP ERREOF ;END OF FILE 
.BYTE "SROTCES EERF " 



3669 FSCML = *-FSCM 

35 .INCLUDE #E: 

40 .INCLUDE #D:ATFMS3. 



SRC 



81 



ATARI DOS 2.0S 



LIST DIRECTORY 



0E21 




4000 
4001 
4002 
4003 
4004 


0E2L 


A000 


4005 


0E2 3 


A920 


4006 


0E25 


9147 


4007 


0E2 7 


AE0513 


4008 


0E2i\ 


BD0114 


4009 


0E2D 


2920 


4010 


0E2ir 


F004 


4011 


0E31 


A92A 


4012 


0E3:3 


9147 


4013 


0E3!; 


C8 


4014 


0E3i5 


A920 


4015 


0E3I3 


9147 


4016 


0E3A 


C8 


4017 
4018 


0E3I! 


BD0614 


4019 


0E31i; 


9147 


4020 


0E4I!I 


E8 


4021 


0E4;. 


C8 


4022 


0E4:> 


C00D 


4023 


0E44 


90F5 


4024 
4025 


0E4(i 


A920 


4026 


0E4(i 


9147 


4027 


0E4A 


C8 


4028 


0E4H 


8C0F13 


4029 
4030 


0E4i; 


AE0513 


4031 


0E5]. 


BC0214 


4032 


0E54 


BD0314 


4033 
4034 
4035 


0E57 


A264 


4036 


0E59 


20710E 


4037 


0E5C; 


A20A 


4038 


0E5i; 


20710E 


4039 


0E6]. 


98 


4040 


0E6:: 


208D0E 


4041 
4042 


0E6!i 


A011 


4043 


0E67 


A99B 


4044 


0E6S' 


9147 


4045 


0E6Ei 


A000 


4046 


0E6r> 


8C0F13 


4047 


0E7e' 


60 


4048 
4049 


0E71 


8E0E13 


4050 



.PAGE 
; FORMAT DIR ENTRY INTO A SECTOR BUFFER 
FDENT 



LDY #0 

LDA *$20 

STA (ZSBA),Y 

LDX CDIRD 

LDA FILDIR+DFDFLl.X 

AND #DFDLOC ;BUT IF FILE LOCKED 

BEQ LDl 

LDA # ' * 

STA (ZSBA),Y 

INY 

LDA #$20 

STA (ZSBA),Y 

INY 



; START AT DISPL ZERO 
; START WITH A BLANK 



; CHANGE TO AST 

J FOLLOWED BY A BLANK 



LD2 



LDA FILDIR+DFDPPN,X ;MOVE THE 12 CHAR 

STA (ZSBA),Y ;FILE NAME 

I NX 

INY 

CPY #13 

BCC LD2 



LDA #S20 

STA (ZSBA),Y 

INY 

STY TEMP4 



.•FOLLOWED BY A BLANK 
;SAVE INDEX =15 



LDX CDIRD 

LDY PILDIR+DFDCNT,X ;SET A,Y 

LDA FILDIR+DFDCNT+1,X r=SECTOR COUNT 



LDX #100 

JSR CVDIGIT 

LDX #10 

JSR CVDIGIT 

TYA 

JSR STDIGIT 

LDY #17 

LDA #EOL 

STA (ZSBA),Y 

LDY #0 

STY TEMP4 
RTS 



CVDIGIT STX TEMP3 



CVDY 



; CONVERT AND MOVE 
;100S DIGIT 

;10S DIGIT 

;1S DIGIT 

;THEN PUT OUT 
;AND EOL 

;SET CHAR CNT = 

rSAVE DIGIT VALUE 



LIST DIRECTORY 



0E74 A2FF 


4051 
4052 ; 


LDX 


#SFF 




0E76 8D0D13 


4053 CVDl 


STA 


TEMP2 


;SAVE CURR VALUE HI 


0E79 8C0C13 


4054 


STY 


TEMPI 


?AND LOW 


0E7C E8 


4055 


INX 




; INC DIGIT COUNTER 


0E7n 38 


4056 


SEC 




JSUBRTACT DIGIT VAU 


0E7E AD0C13 


4057 


LDA 


TEMPI 


;PROM CUR VALUE 


0E81 ED0E13 


4058 


SBC 


TEMP3 




0E84 AS 


4059 


TAY 






0E85 AD0D13 


4060 


LDA 


TEMP2 




0E88 E900 


4061 


SBC 


#0 





82 



ATARI DOS 2.0S 



0E8A 


B0EA 


4062 
4063 


BCS 


CVDl 


0E8(: 


8A 


4064 


TXA 




0E8I) 


0930 


4065 


STDIGIT ORA 


#?30 


0E81? 


AC0F13 


4066 


LDY 


TEMP4 


0E9:J 


9147 


4067 


STA 


(ZSBA),Y 


0E94 


EE0F13 


4068 


INC 


TEMP4 


0E97 


AD0D13 


4069 


LDA 


TEMP2 


0E9A 


AC0C13 


4070 


LDY 


TEMPI 


0E915 


60 


4071 


RTS 





;IF NOT GONE MINUS, DO AGAIN 

; DIGIT TO ACU 
;PLUS ASCII ZERO 
;GET OUTPUT INDEX 
;AND SET DIGIT 
; INC OUTPUT INDEX 
;LOAD VALUE HI 
;AND VALUE LO 



FILE NAME DECODE 



0E9E 



0E9E BD4403 
0EA1 8543 
0EA3 BD4503 
0EA6 8544 
0EAB A002 
0EAh B143 
88 

3058 
C93A 
D0F7 



0EAC 
0EAD 
0EAF 
0EB1 



0EB3 C8 



0EB4 A20B 
0EB6 A920 



4072 
4073 
4074 
4075 
4076 
4077 
4078 
4079 
4080 
4081 
4082 
4083 
4084 
4085 
4086 
4087 
4088 
4089 
4090 
4091 
4092 
4093 
4094 
4095 
4096 

4097 
4098 
4099 
4100 
4101 
4102 
4103 
4104 
4105 
4106 
4107 
4108 
4109 
4110 
4111 
4112 



.PAGE "FILE NAME DECODE" 

FNDCODE - DECODE A FILE NAME 

THE USER FILENAME IS POINTED TO BY 
ZBUFP, IT IS ON THE FORM P.X WHERE P 
IS THE PRIMARY FILE NAME (1 TO 8 CHARS) 
AND X IS THE EXTENDED FILE NAME 
(0 TO 4 CHARS). THE PERIOD IS OPTIONAL 
(IF NOT PRESENT, THEN NO EXTENSION). 
THE DECODED FILENAME WILL BE 12 CHARS 
IN LENGTH. THE P FIELD WILL BE 
LEFT JUSTIFIED IN THE 1ST 8 BYTES. 
THE X FIELD WILL BE LEFT JUSTIFIED IN 
THE LAST 4 BYTES. BLANKS ARE USED 
TO PAD THE FIELDS TO FULL SIZE. 
IF THE USER SPECIFIED P OR X FILEDS 
CONTAIN MORE THAN 8 OR 4 CHARS, THEN THE 
EXTRA CHARS ARE IGNORED. THE '*' 
WILD CARD CHAR WILL CAUSE THE REST 
OF THE FIELDS TO FILLED WITH THE 
'?■ WILD CARD CHAR. ANY NON-ALPHANUMERIC 
CHAR TERMINATES THE FILENAME. 

FNDCODE 



FD0A 



FD0B 



FNDCNX 



LDA 


ICBAL,X 




STA 


ZBUFP 




LDA 


ICBAH,X 




STA 


ZBUFP+1 




LDY 


#2 


;FIND THE 


LDA 


( ZBUFP ),Y 




DEY 






BMI 


FNDERR 


;BR IF 25 


CMP 


#' : 




BNE 


FD0A 





■D' 



LDX 

LDA 



#11 
*$20 



0EB8 9D5913 4113 FD0 

4114 

4115 

4116 ; 

0EBE A200 4117 

0EC0 8E0C13 4118 

4119 ; 

4120 ; 

4121 FDl 
4122 



0EBB CA 
0EBC 10FA 



0EC3 C8 
0EC4 B143 



STA FNAME,X 

DEX 

BPL FD0 

LDX #0 

STX EXTSW 



r CLEAR FILENAME TO BLANKS 



;SET FNAME CHAR CNT TO 
;SET NOT IN EXTENSION 



INY 

LDA 



;INC ZBUFP INDEX 
(ZBUFP), Y rGET BUF CHAR 



83 



ATARI DOS 2.0S 



FILE NAME DECODE 







4123 


; 






0EC6 


C92A 


4124 




CMP 


#'* • 


0EC8 


D00B 


4125 
4126 


; 


BNE 


Fr3 ; 


0ECA 


A93F 


4127 


FD2 


LDA 


#'? ; 


0ECC 


200A0F 


4128 




JSR 


FDSCHAR ; 


0ECF 


90F9 


4129 




BCC 


FD2 ; 


0ED1 


10F0 


4130 




BPL 


FDl ; 


0ED3 


302E 


4131 
4132 


, 


BMI 


FDEND ; 


0ED5 


C92E 


4133 


FD3 


CMP 


#•• : 


0ED7 


D00C 


4134 




BNE 


FD4 ; 


0ED9 


2C0C13 


4135 




BIT 


EXTSW 


0EDC 


3025 


4136 




BMI 


FDEND ; 


0EDE 


A208 


4137 




LDX 


#8 ; 


0EE0 


6E0C13 


4138 




ROR 


EXTSW 


0EE3 


90DE 


4139 
4140 


, 


BCC 


FDl ; 


0EE5 


C93F 


4141 


FD4 


CMP 


#'? W 


0EE7 


F014 


4142 
4143 


, 


BEQ 


FD6 ; 


0EE9 


C941 


4144 




CMP 


#'A ; 


0EEB 


9004 


4145 




BCC 


FD5 


0EED 


C95B 


4146 




CMP 


#$5B ; 


0EEF 


900C 


4147 
4148 


; 


BCC 


FD6 ; 


0EF1 


E000 


4149 


FD5 


CPX 


#0 


0EF3 


F012 


4150 
4151 


; 


BEQ 


FNDERR 


0EF5 


C930 


4152 




CMP 


#$30 


0EF7 


900A 


4153 




BCC 


FDEND 


0EF9 


C93A 


4154 




CMP 


#$3A ; 


0EFB 


B006 


4155 
4156 


, 


BCS 


FDEND ; 


0EFD 


200A0F 


4157 


FD6 


JSR 


FDSCHAR r 


0F00 


4CC30E 


4158 
4159 


. 


JMP 


FDl : 


0F03 


AE0113 


4160 


FDEND 


LDX 


CURFCB ; 


0F06 


60 


4161 
4162 


r 


RTS 




0F07 


4CC512 


4163 


FNDERR 


JMP 


ERRFN 



TEST FOR WILD CARDS 
BR NOT WILD CARD 

LOAD 7 WILD CARD 

GO STORE IT 

BR IF PORX NOT FULL 

BR IF AT START OF X 
BR IF AT X END 

WAS CHAR FIELD SEPERATOR 

BR IF NOT 

WAS THERE ALREADY 1 CHAR 

BR IF WAS END 

ADV FNAME INDEX TO XFIELD 

SET EXTSW - MINUS 

CONT WITH NEXT CHAR 

WAS IT WILD CARD 
BR IF WILD CARD 

IS CHAR ALPHA 
BR NOT ALPHA 
TEXT HI ALPHA 
BR IF NOT APLHA 

IF FIRST CHAR NOT 
ALPHA THEN ERROR 

IS CHAR NUMERIC 
BR NOT NUMERIC (END OF NAME) 
TEST NUMERIC HI 
BR NO NUMBER 

STORE THE CHAR 

AND CONTINUE WITH NEXT 

RESTORE X REG 



INDICATE FILENAME ERROR 



FMS - 128/256 BYTE SECTOR (2.0S) 
FILE NAME DECODE 



0F0A 




4164 


.PAGE 








4165 












4166 


; FDSCHAR - 


STORE FILENAME CHAR 








4167 












4168 


; ON ENTRY 










4169 


; A = CHAR 










4170 


; X = NEXT 


FN POSITION 








4171 












4172 


; ON EXIT 










4173 


; CARRY - SET IF FIELD FULL 








4174 


; MINUS - IF START OF EXECUTION 








4175 


; PLUS - IF END OF EXECUTION 








4176 


; 










4177 


FDSCHAR 






0F0A 


E008 


4178 


CPX 


#8 ;AT EXECUTION 


0F0C 


900D 


4179 


BCC 


FDSC2 ;BR IF NOT 




0F0E 


F005 


4180 
4181 


BEO 


FDSCl ;BR IF 1ST 


CHAR OF 


0F10 


E00C 


4182 


CPX 


#12 ;AT END OF 


EXIT 


0F12 


9007 


4183 


BCC 


FDSC2 ;BR NOT AT 


END 



84 



ATARI DOS 2.0S 



0F14 60 


4184 
4185 ( 


RTS 




0F15 2C0C13 


4186 FDSCl 


BIT 


EXTSW 


0F18 3001 


4187 


BMI 


FDSC2 


0F1A 60 


4188 
4189 ; 


RTS 




0F1B 9D5913 


4190 FDSC2 


STA 


FNAME.X 


0F1E E8 


4191 


INX 




0F1F 18 


4192 


CLC 




0F20 60 


4193 


RTS 





;DO NOT STORE CHAR UNLESS 
; PERIOD WAS SEEN 



;SET CHAR INTO NAME 
;INC TO NEXT CHAR 



DIRECTORY SEARCH 



0F21 




4194 




.PAGE "DIRECTORY SEARCH" 






4195 , 














4196 ; 


SFDIR - SEARCH FILE 


DIRECTORY 






4197 


CSFDIR - FILE DIRECTORY SEARCH 






4198 














4199 


THE 


FILE DIRECTORY 


IS SEARCHED FOR THE 






4200 


FILENAME IN FNAME . 


THE SEARCH STARTS 






4201 


AT THE CENTRAL SECTOR+1 AND WILL CONTINUE 






4202 


FOR 


UP TO 


A TOTAL OF 8 SECTORS. WHEN 






4203 


TESTING FOR FNAME MATCH, '7' FNAME 






4204 


CHARS WILL ALWAYS MATCH THE CORESPONDING 






4205 


DIR 


FILENAME CHAR. 


IF A MATCH IS FOUND 






4206 


CDIRS CONTAINS THE 


RELATIVE DIRECTORY SECTOR 






4207 


NUMBER (0 


-7) AND CDIRD (AND THE Y REG) 






4208 


CONTAINS THE DISPLACEMENT OF THE ENTRY. 






4209 


AFTER A MATCH HAS BEEN FOUND, THE DIRECTORY CAN 






4210 


BE SEARCHED FOR ANOTHER MATCH VIA THE CSFDIR 






4211 


ENTRY POINT. IF A 


MATCH HAS NOT BEEN FOUND 






4212 


THEN DHOLES AND DHOLED WILL POINT TO A 






4213 


DIRECTORY 


HOLE THAT 


CAN BE USED. 






4214 


• IF DHOLED 


= FF THEN THE DIRECTORY IS FULL. 






4215 


THE 


CARRY 


IS RETURNED CLEAR IF FILE FOUND, 






4216 


SET 


IF FILE NOT FOUND. 






4217 














4218 


3FDIR 








0F21 


A9FF 


4219 




LDA 


#$FF 


;INIT TO -1 


0F23 


8D0213 


4220 




STA 


DHOLES 


;DIR HOLE SECTOR 


0F26 


8D0613 


4221 




STA 


CDIRS 


;CUR DIR SECTOR 


0F29 


8D0713 


4222 




STA 


SFNUM 


;FILE NUMBER 


0F2C 


A970 


4223 




LDA 


#570 


;INIT TO -16 (-ENTRY LENGTH) 


0E2E 


8D0513 


4224 
4225 


• 


STA 


CDIRD 


;CUR DIR DISPL 






4226 


::sFDiR 






0F31 


EE0713 


4227 




INC 


SFNUM 




0F34 


18 


4228 




CLC 






0F35 


AD0513 


4229 




LDA 


CDIRD 


;CDIRD=CDIRD+ENTRY LEN 


0S38 


6910 


4230 




ADC 


#DFDELN 




0B3A 


1011 


4231 




BPL 


SFD2 


;IF RESULT <128 THEN BR 






4232 


; ELSE AT END OF DIR 


SECT 


0F3C 


EE0613 


4233 




INC 


CDIRS 


,-INC TO NEXT DIR SECTOR 


0F3F 


A908 


4234 




LDA 


#8 


;TEST END OF DIR 


0F41 


CD0613 


4235 




CMP 


CDIRS 




0F44 


9002 


4236 




BCC 


SPDl 


;BR NOT END 


0F46 


F048 


4237 
4238 




BEQ 


SDRTN 




0F48 


206E10 


4239 


3FD1 


JSR 


RDDIR 


;READ THE NEXT DIR RECORD 


0S'4B 


A900 


4240 
4241 


, 


LDA 


#0 


;SET DIR DISPL = 


0I'4D 


8D0513 


4242 


SFD2 


STA 


CDIRD 


;SET NEW DIR DISPL 


0F50 


A8 


4243 
4244 


r 


TAY 




;PUT DISPL IN Y AS INDEX 



85 



ATARI DOS 2.0S 



DIRECTORY SEARCH 



0F5;. 
0F54 

0F5<i 
0F5B 
0F5/1 



B90114 
F01D 

301B 
2901 
D0D5 



0F5C 
0F5i: 
0F6] 
0F6;i 

0F6;; 

0F6£: 

0F6;i. 

0F6E. 
0F6C 
0F6F 

0F7ei 

0F73 



0F73 
0F7fi 



0F761 
0F7E: 
0F7E; 
0F81 
0F84 
0F87 

0F8f. 
0F8ri 



A200 

BD5913 

C93F 

F005 

D90614 

D0C7 

E8 

C8 

E00B 

D0EE 

18 
901D 



AD0213 
1012 



AD0613 
8D0213 
AD0513 
8D0313 
AD0713 
8D0413 

B90114 
30A2 



0F8F 38 



0F90 
0F93 



AE0113 
60 



4245 
4246 

4247 
4248 
4249 
4250 
4251 
4252 
4253 
4254 
4255 
4256 

4257 
4258 
4259 
4260 
4261 
4262 
4263 
4264 
4265 
4266 
4267 
4268 
4269 
4270 
4271 
4272 
4273 
4274 
4275 
4276 
4277 
4278 
4279 
4280 
4281 
4282 
4283 
4284 

4285 
4286 



LDA FILDIR+DFDFLl.Y :GET FLAG 1 

BEQ SFDSH ;BR IF UNUSED (END OF USED 

ENTRIES) 
BMI SFDSH ;BR IF DELETED 
AND #DFDOUT ;IF OPEN OUTPUT 
BNE CSFDIR ;DON'T FIND IT 



ENTRY IN USE, TEST FOR MATCH 



SFD3 



SFD4 



LDX 
LDA 
CMP 
BEQ 

CMP 

BNE 
INX 
INY 
CPX 
BNE 

CLC 
BCC 



LDA 
BPL 



#0 ;TEST MATCH ON 12 CHARS 
FNAME.X ;FILE NAME CHAR 
#'7 ;IS FNC WILD CARD 
SFD4 ;THEN IT MATCHES 
FILDIR+DFDPFN.Y ;ELSE IT MUST MATCH FOR 

REAC 
CSFDIR ;IF NOT MATCH THEN TRY NEXT 
;INC CHAR CNT 



; ELSE 

LDA 
STA 
LDA 
STA 
LDA 
STA 

SFDSHl LDA 
BMI 



#11 
SFD3 



SDRTN 



DHOLES 
SFDSHl 



CDIRS 

DHOLES 

CDIRD 

DHOLE D 

SFNUM 

DHFNUM 



;TEST ALL 

rAND CONTINUE CHECK 



;WE HAVE A MATCH 



rIF DHOLES NOT MINUS 

;THEN ALREADY HAVE A GOOD HOLE 



;MOVE CURR DISPL SECTOR 
;AND CURRENT DIR DISPL 
;T0 HOLE SECTOR AND DISPL 

;SAVE HOLE 
;FILE NUMBER 



FILDIR+DFDFLl.Y ;IF HOLE WAS A DELETED 
CSFDIR : ENTRY THEN CONTINUE 



ELSE WE ARE AT END OF 



SDRTN LDX CURFCB 
RTS 



;USED ENTRIES THUS FILE NOT 

FOUND 
: RESTORE X REG 



WRITE DATA SECTOR 



0F94 



0F94 
0F97 

0F99 
0F9A 

0F9C 
0F9E 
0FAe 
0FA3 
0FA5 



BD8513 
300F 

0A 
1009 

0A 

9D8513 

20F80F 

3024 

4C0F10 



4287 
4288 
4289 
4290 
4291 
4292 
4293 
4294 
4295 
4296 
4297 
4298 
4299 
4300 
4301 
4302 
4303 



.PAGE "WRITE DATA SECTOR" 
; WRTNXS - WRITE NEXT SECTOR 
WRTNXS 



LDA FCBFLG.X 
BMI WRTNl 



ASL 
BPL 

ASL 
STA 
JSR 
BMI 
WRUl JMP 



A 
WRUl 

A 

FCBFLG.X 

WRCSIO 

WRNERR 

RDNXTS 



;IF ACQUIRING SECTORS 
fTHEN NOT UPDATE 



;IF SECTOR NOT MODIFIED 
;THEN DON'T IT 



.•TURN OFF FLAG BITS 
rWRITE CURRENT SECTOR 
.•BR IF BAD I/O 
;ELSE READ NEXT SECTOR 



86 



ATARI DOS 2.0S 



0FAB 


2006H 


4304 
4305 


WRTNl 


JSR 


GETSECTOR 


•GET A NEW SECTOR 


0FAH 


BD8713 


4306 


WRTLSEC LDA 


FCBDLN.X 


•GET DATA LEN 


0FAIi; 


ACFB12 


4307 


WRTLSl 


LDY 


DRVLBT 


•INTO LAST BYTE 


0fb:l 


9147 


4308 
4309 


. 


STA 


(ZSBA),Y 


•OF SECTOR 


0FB;i 


BD8C13 


4310 


WRTN2 


LDA 


FCBLSN+1 , X 


;MOVE LINK SECTOR 


0FB(J 


1D8113 


4311 




ORA 


FCBFNO.X 


•PLUS FILE NUM 


0FB9 


ACF812 


4312 




LDY 


DRVMDL 


•TO BYTES 126,127 


0FB(: 


9147 


4313 




STA 


(ZSBA),Y 


;0F SECTOR BUFF 


0FB1S 


C8 


4314 




INY 






0FB1? 


BD8B13 


4315 




LDA 


FCBLSN.X 




0FC:2 


9147 


4316 
4317 


, 


STA 


(ZSBA),Y 




0FC4 


20F80F 


4318 




JSR 


WRCSIO 


.•WRITE SECTOR 


0FC7 


1011 


4319 
4320 


. 


BPL 


WRTN5 


;BR NOT ERROR 


0FC') 


AD0303 


4321 


WRNERR 


LDA 


DCBSTA 


rSAVE ERROR STATUS 


0FC<: 


8D0F13 


4322 




STA 


TEMP4 




0FC1? 


A900 


4323 




LDA 


#0 


; CLOSE FILE 


0FDL 


9D8213 


4324 




STA 


FCBOTCX 




0FD4 


AD0F13 


4325 




LDA 


TEMP4 


; RECOVER ERROR CODE 


0FD7 


4CD312 


4326 
4327 
4328 


! 
WRTN5 


JMP 


RETURN 




0FD,\ 


FE8F13 


4329 




INC 


FCBCNT.X 


:INC SECTOR CNT 


0fd:3 


D003 


4330 




BNE 


WRTN6 




0fd:? 


FE9013 


4331 
4332 


WRTN6 


INC 


FCBCNT+1 , X 




0FE2 


200210 


4333 




JSR 


MVLSN 


;LINK TO CUR 


0FE5 


A900 


4334 




LDA 


#0 




0FE7 


9D8B13 


4335 




STA 


FCBLSN.X 


;LINK = 


0FEA 


9D8C13 


4336 




STA 


FCBLSN+1, X 




0FED 


9D8713 


4337 




STA 


FCBDLN.X 


;DLN = 



WRITE DATA SECTOR 



0FFI3 


ADF812 


4338 




LDA 


DRVMDL 


0FF3 


9D8613 


4339 
4340 


WRNRTS 


STA 


FCBMLN.X 


0FF5 


18 


4341 




CLC 




0FF7 


60 


4342 
4343 


; 


RTS 




0FF3 


38 


4344 


WRCSIO 


SEC 


;WRITE CUR 


0FF9 


BD8A13 


4345 


RWCSIO 


LDA 


FCBCSN+1,X 


0ff: 


BC8913 


4346 




LDY 


FCBCSN.X 


0FFF 


4CF711 


4347 
4348 


, 


JMP 


DSIO 


1002 


BDSBIS 


4349 


MVLSN 


LDA 


FCBLSN.X rMOVE LINK 


1005 


9D8913 


4350 




STA 


FCBCSN.X 


100B 


BD8C13 


4351 




LDA 


FCBLSN+1, X 


100B 


9D8A13 


4352 




STA 


FCBCSN+1,X 


100E 


60 


4353 
4354 


, 


RTS 




100F 




45 




.INCLUDE #E: 


100F 




50 




.INCLUDE #D:ATFMS4.SRC 



RE*.D DATA SECTOR 



.PAGE "READ DATA SECTOR" 
RDNXTS - READ NEXT SECTOR 



10eiF 5000 
5001 
5002 

5003 ; 

5004 RDNXTS 

10flF BD8513 5005 LDA FCBFLG.X .-IF NOT UP0 MODE 
1012 F003 5006 BEQ RDNSO ;BR 



87 



ATARI DOS 2.0S 



1014 


4C940F 


5007 




JMP 


WRTNXS 


.-ELSE WRITE FIRST 


1017 




5008 


RDNSO 


= 


* 




1017 


BD8B13 


5009 




LDA 


FCBLSN,X 


;IF LSN NOT 


101A 


1D8C13 


5010 




ORA 


FCBLSN+1,X 


,- ZERO 


101D 


D002 


5011 




BNE 


RDNSl 


;BR 


101F 


38 


5012 




SEC 




;ELSE EOF 


1020 


60 


5013 




RTS 






1021 


200210 


5014 


RDNSl 


JSR 


MVLSN 


rMOVE LINK TO CURRENT 


1024 


18 


5015 




CLC 




;READ 


1025 


20F90F 


5016 




JSR 


RWCSIO 


; CURRENT SECTOR 


1028 


3035 


5017 
5018 




BMI 


RDIOER 


,-BR IF OK READ 






5019 


; ELSE 


GOTO 


I/O ERROR 








5020 










102A 


ACF812 


5021 




LDY 


DRVMDL 




102D 


B147 


5022 




LDA 


(ZSBA) ,Y 


,-TEST FOR SAME 


102F 


29FC 


5023 




AND 


*$FC 


rFILE NO 


1031 


DD8113 


5024 




CMP 


FCBFNO.X 




1034 


D02C 


5025 
5026 




BNE 


RDFNMM 


;IF NOT THEN ERROR 


1036 


B147 


5027 




LDA 


(ZSBA) ,Y 


;MOVE LINK SECTOR 


1038 


2903 


5028 




AND 


#$03 




103A 


9D8C13 


5029 




STA 


FCBLSN+1,X 




103D 


C8 


5030 




I NY 






103E 


B147 


5031 




LDA 


(ZSBA),Y 




1040 


9D8B13 


5032 
5033 


! 


STA 


FCBLSN,X 




1043 


C8 


5034 




I NY 




;INC TO LEN BYTE 


1044 


B147 


5035 




LDA 


(ZSBA) ,Y 


;GET LEN BYTE 


1046 


48 


5036 




PHA 




;SAVE IT 


1047 


BD8413 


5037 




LDA 


FCBSLT.X 


;GET SECTOR LEN TYPE 


104A 


D008 


5038 
5039 


, 


BNE 


RDNS3 


;BR IF NEW TYPE 


104C 


68 


5040 




PLA 




rGET LEN 


104D 


3002 


5041 




BMI 


RDNS2 


;BR IF OLD SHORT SECTOR 


104F 


A97D 


5042 




LDA 


#125 


;ELSE SET FULL SECTOR 


1051 


297F 


5043 


RDNS2 


AND 


#S7F 


jTURN OFF MSB 


1053 


48 


5044 
5045 


, 


PHA 




; BALANCE STACK 


1054 


68 


5046 


RONS 3 


PLA 






1055 


9D8613 


5047 
5048 




STA 


FCBMLN.X 


;SET MAX LEN 


1058 


A900 


5049 




LDA 


#0 


;SET CUR DATA LEN = 


105A 


9D8713 


5050 




STA 


FCBDLN.X 





READ DATA SECTOR 



105D 


18 


5051 




CLC 






105E 


60 


5052 




RTS 






105F 


20E512 


5053 


RDIOER 


JSR 


ERRIO 


;I/0 ERROR 


1062 




5054 


RDFNMM 


= 


* 


jFILE mjMBER MISMATCH 


1062 


BD4203 


5055 




LDA 


ICCOM.X 




1065 


C921 


5056 




CMP 


#$21 


rWAS THIS DELETE 


1067 


F003 


5057 




BEQ 


RDDELE 


;BR IF DELETE 


1069 


20C712 


5058 




JSR 


ERFNMM 


;BR NOT DELETE 


106C 


38 


5059 


RDDELE 


SEC 




; INDICATE EOF TO DELETE 


106D 


60 


5060 
5061 


, 


RTS 







READ/WRITE DIR 



106E 



106E 18 



5062 
5063 
5064 
5065 
5066 RDDIR CLC 



.PAGE "READ/WRITE DIR" 
RDDIR/WRDIR READ/WRITE DIRECTORY 
;SET READ 



ATARI DOS 2.0S 



i0e.F 


9001 


5067 
5068 


, 


BCC 


DIRIO 




1071 


38 


5069 
5070 


WRTDIR 


SEC 




SET WRITE 


1072 


08 


5071 


DIRIO 


PHP 




SAVE READ WRITE 


107 3 


A914 


5072 




LDA 


#FILDIR/256 rMOVE BUF ADDR 


1075 


8D0503 


5073 




STA 


DCBBUF+1 , 


TO DCB 


1078 


A901 


5074 




LDA 


#FILDIRJ.255 


107A 


8D0403 


5075 
5076 


. 


STA 


dcb6uf 




107D 


18 


5077 




CLC 






10-E 


AD0613 


5078 




LDA 


CD IRS 


CDIRS+ 


10fil 


6969 


5079 




ADC 


#S69 


((40*18)/2)+l 


10f!3 


A8 


5080 




TAY 




INTO A,Y 


10EI4 


A901 


5081 




LDA 


#1 


IS DIR SECTOR NUMBER 


10EI6 


6900 


5082 
5083 


. 


ADC 


*0 




10(18 


4CAB10 


5084 
5085 


; 


JMP 


DSYSIO 


GO DO SYSTEM I/O 


READ/WRITE 


VTOC 










10HB 




5086 




.PAGE "READ/WRI 


rE VTOC" 






5087 


. 












5088 


; RDVTOC/WRCTOC - READ/WRITE VTOC 






5089 


; 












5090 


RDVTOC 








108B 


A005 


5091 




LDY 


♦DVDWRQ 


•IF WRITE REQD 


108D 


B145 


5092 




LDA 


(ZDRVA),Y 




10«F 


F001 


5093 




BEQ 


RDVGO 




1091 


60 


5094 




RTS 






10<»2 


18 


5095 


RDVGO 


CLC 




;SET READ 


1093 


9007 


5096 
5097 


, 


BCC 


VTIO 








5098 


WRTVTOC 






1095 


A005 


5099 


WRVTOC 


LDY 


♦ DVDWRQ 


■TURN OFF 


1097 


A900 


5100 




LDA 


#0 


•WRITE READ 


1099 


9145 


5101 




STA 


(ZDRVA),Y 




109B 


38 


5102 
5103 
5104 


; 


SEC 






109C 


08 


5105 


VTIO 


PHP 




•SAVE R/W 


109D 


A546 


5106 




LDA 


ZDRVA+1 


■MOVE BUF ADDR 


10?IF 


8D0503 


5107 




STA 


DCBBUF+1 


•TO DCB 


10;i2 


A545 


5108 




LDA 


ZDRVA 




10;i4 


8D0403 


5109 
5110 


; 


STA 


DCBBUF 




10^1 7 


A068 


5111 




LDY 


#S68 


•READ SECTOR 


10;i9 


A901 


5112 
5113 
5114 


DSYSIO 


LDA 


#1 


• (40*18)/2 


i0;iB 


28 


5115 
5116 


DSYSIA 


PLP 






i0;,c 


AEFE12 


5117 




LDX 


DRVTYP 


•LOAD DRIVE TYPE 


i0;iF 


206C07 


5118 




JSR 


BSIO 


■GO DO I/O 


10112 


3001 


5119 




BMI 


DSIOER 


•BR IF ERROR 


10E14 


60 


5120 
5121 
5122 


; 


RTS 




RETURN 


10E15 


C983 


5123 


DSIOER 


CMP 


#DCBDER 


WAS IT DATA ERROR 


10BI7 


F003 


5124 




BEQ 


DEAD 


BR IF WAS 


10E19 


4CE512 


5125 
5126 


. 


JMP 


ERRIO 


ELSE USER PROBLEM 


10E1C 


4CC912 


5127 
5128 
5129 
5130 


DEAD 

; 

; OPEN 


JMP 
VTOC 


ERRSYS 


FATAL ERROR 



89 



ATARI DOS 2.0S 



5131 OPVTOC 



10B:F 208B10 5132 

10C2 4C9510 5133 

5134 

5135 

5136 



JSR 
JMP 



RDVTOC 
WRTVTOC 



;READ IT 
;THEN WRITE IT 



INSURES NOT PROTECTED 



PREK SECTOR 
10C!> 



10C!> 
10C» 
10CH 
10C1) 
10C1' 
10D:. 
10D4 
10D-' 
10D() 
10D9 



BD8913 

1D8A13 

F038 

A900 

A003 

5E8A13 

7E8913 

eA 

88 

D0F6 



10DEI A005 

10DI> eA 

10Di; 88 

10Dr D0FC 

10E]. A8 

10e;! A900 

10E4 38 

10E!; GA 

10E(; 88 

10EV 10FC 

10E9 48 

10E?. BD8913 

10EII 690A 

10EI' A8 

10Fei 68 

10F] 1145 

10f;: 9145 



10F5 
10F7 
10FSI 
10F/. 
10FC: 
10FI 
10FF 
1101 
1103 

110! 
110! 



A003 

B145 

18 

6901 

9145 

C8 

B145 

6900 

9145 



5137 
5138 
5139 
5140 
5141 
5142 
5143 
5144 
5145 
5146 
5147 
5148 
5149 
5150 
5151 
5152 
5153 
5154 
5155 
5156 
5157 
5158 
5159 
5160 
5161 
5162 
5163 
5164 
5165 
5166 
5167 
5168 
5169 
5170 
5171 
5172 
5173 
5174 
5175 
5176 
5177 
5178 
5179 
5180 
5181 
5182 
5183 
5184 
5185 



.PAGE "FREE SECTOR" 

; 

; FRESECT - FREE CURRENT SECTOR 



FRESECT 



FSl 



FS2 



FS3 



LDA 


FCBCSN.X 


ORA 


FCBCSN+1,X 


BEQ 


FSRTS 


LDA 


*0 


LDY 


#3 


LSR 


FCBCSN+1,X 


ROR 


FCBCSN.X 


ROR 


A 


DEY 




BNE 


FSl 


LDY 


#5 


ROR 


A 


DEY 




BNE 


FS2 


TAY 




LDA 


#0 


SEC 




ROR 


A 


DEY 




BPL 


FS3 


PHA 




LDA 


FCBCSN.X 1 


ADC 


fDVDSMP i 


TAY 




PLA 




ORA 


(ZDRVA),Y ■ 


STA 


(ZDRVA).Y ; 


LDY 


#DVDNSA : 


LDA 


(ZDRVA).Y 


CLC 




ADC 


#1 


STA 


(ZDRVA) .Y 


INY 




LDA 


(ZDRVA),Y 


ADC 


#0 


STA 


( ZDRVA ) , Y 



; DIVIDE SECTOR # 

;BY 3 TO GET BYTE NO 
rWITH REM IN ACU 



TO FOR BYT BIT NO 



■BIT NO (0-7) INTO Y 

SHIFT IN A BIT 

TO PROPER LOCATION 



rSAVE MASK 

GET BYTE NO 

ADD OFFSET TO SMAP 
■RESULT IS VTOC INDEX 

GET BIT MASK 

OF BIT TO BIT MAP 

AND SET RESULTS 

INC NO OF SECTORS AVAIL 



FSRTS 



GET SECTOR 
11106 



.PAGE "GET SECTOR" 



5186 

5187 ; 

5188 ; GET SECTOR - GET A FREE SECTOR FOR 

5189 ; USE IN FCB AT X REG. THE SECTOR 

5190 jNUMBER IS PLACED IN FCBLSN 



90 



ATARI DOS 2.0S 



net Aei09 

110fl C8 
110?i C064 
110B B054 
110D B145 
110F F0F7 



1111 
1114 
lli;i 
llKi 
lllH 
lllA 

iiic; 
mi: 

lllF 

112:. 
ii2;t 



8C0C13 

48 

38 

A003 

B145 

E901 

9145 

C8 

B145 

E900 

9145 



1121; C8 
112r) A9FF 
1120 9145 

112A 68 
112H A0FF 

1121) C8 
1121! 0A 
1121' 90FC 
1131 8C0D13 
1134 4A 
88 
10FC 
11313 AC0C13 
11313 9145 



11315 
11315 



5191 
5192 
5193 
5194 
5195 
5196 
5197 
5198 
5199 
5200 
5201 
5202 
5203 
5204 
5205 
5206 
5207 
5208 
5209 
5210 
5211 
5212 
5213 
5214 
5215 
5216 
5217 
5218 
5219 
5220 
5221 
5222 
5223 
5224 
5225 
5226 
5227 
5228 
5229 
5230 
5231 
5232 
5233 
5234 
5235 
5236 



THE SEARCH FOR A FREE SECTOR STARTS 
AT THE DVDSMP BYTE. SECTORS ARE 
NUMBERED SEQUENTIALLY FROM ZERO TO 
MAXSM WITH THE LEFT BIT OF THE DVDSMP 
BEING WITH ZERO. 



GETSECTOR 
LDY 



GSl 



GS3 



#DVDSMP-1 ;SET Y TO START MAP-1 



I NY ;INC SMAP INDEX 

CPY ♦90+DVDSMP ;AT END OF MAP? 

BCS GSERR ;BR IF AT END 

LDA (ZDRVA),Y ; GET A MAP BYTE 

BEQ GSl ;BR NO FREE SECTOR IN BYTE 



;SAVE MAP INDEX 

;DEC NO OF SECTORS AVAIL 



STY 


TEMPI 




PHA 






SEC 






LDY 


#DVDNSA 




LDA 


(ZDRVA), 


,Y 


SBC 


#1 




STA 


(ZDRVA) , 


,Y 


INY 






LDA 


( ZDRVA ) , 


,Y 


SBC 


#0 




STA 


(ZDRVA) , 


,Y 


INY 






LDA 


#$FF 




STA 


(ZDRVA), 


,Y 


PLA 






LDY 


#$FF 




INY 






ASL 


A 




BCC 


GS2 




STY 


TEMP 2 




LSR 


A 




DEY 






BPL 


GS3 




LDY 


TEMPI 





;SET READ REQD 



;SET BIT COUNTER =-1 

; SHIFT MAP BYTE 

; UNTIL A FREE SECTOR 

; FOUND 

;SAVE BIT NUMBER 

;AND SHIFT BYTE 

; BACKS TO ITS ORIGINAL 

; POSITION AND PUT IT 

rBACK INTO THE MAP 



STA ( ZDRVA ),Y 



GET SECTOR 



113D 38 
1131: AD0C13 
1141. E90A 

1143 A000 
114!i 8C0C13 

1148 0A 

1149 2E0C13 
114(: C8 
1141) C003 
114F 90F7 

115:. 18 
1152 6D0D13 
115,'j 9D8B13 
1158 AD0C13 
115B 6900 



5237 

5238 

5239 

5240 ,- 

5241 

5242 

5243 ; 

5244 GS4 
5245 
5246 
5247 
5248 
5249 r 
5250 
5251 
5252 
5253 
5254 



SEC 

LDA TEMPI 

SBC #DVDSMP 

LDY #0 

STY TEMPI 



A 
TEMPI 



ASL 
ROL 
INY 

CPY #3 
BCC GS4 

CLC 

ADC TEMP2 

STA FCBLSN, 

LDA TEMPI 

ADC #0 



r SECTOR NAP BYTE 
;=DISPL-DVDSMP 



; CLEAR SECT NO HI 
rMULT REL SECTOR MAP 



,-ADD BIT NO TO 
; SECTOR # 
;AND PUT INTO 
; FCBLSN 



91 



ATARI DOS 2.0S 



11;;d 9D8C13 5255 

5256 ; 

1160 60 5257 

5258 ; 

1161 4CCB12 5259 GSERR JMP ERRNSA 

5260 ; 



STA FCBLSN+1 , X 
RTS 



;N0 SECTOR AVAIL 



SETUP ROUTINE 



1164 



1164 A99F 
1166 8549 
1168 8E0113 

116B BA 
11 6C E8 
Hi5D E8 
116E 8E0013 

1171 AE0113 
1174 A421 
1176 8C0103 
1179 88 
117A B92913 
117D 8545 
117F B93113 
1182 8546 

1184 B91113 
1187 F052 
1189 8DFE12 

118C A8 
118D B9F812 
11 '90 8DF812 
ll'>3 B9FB12 
1196 8DFB12 

1199 BC8813 
119C 88 
119D 1031 

119F A000 
llAl B91913 
11A4 F008 
11A6 C8 
11A7 C010 
11A9 90F6 

llAB 4CCD12 

llAE ADFE12 
llBl 4A 
11B2 B010 



5261 
5262 
5263 
5264 
5265 
5266 
5267 
5268 
5269 
5270 
5271 
5272 
5273 
5274 
5275 
5276 
5277 
5278 
5279 
5280 
5281 
5282 
5283 
5284 
5285 
5286 
5287 
5288 
5289 
5290 
5291 
5292 
5293 
5294 
5295 
5296 
5297 
5298 
5299 
5300 
5301 
5302 
5303 
5304 
5305 
5306 
5307 
5308 
5309 
5310 
5311 



.PAGE "SETUP ROUTINE" 

SETUP - A ROUTINE USED FOR ALL COMMANDS 
TO SET UP FMS CONTROLL CELLS 
TO ACCESS A PARTICULAR FILE. 



LDA #$9F 
STA ERRNO 
STX CURFCB 

TSX 
INX 
I NX 
STX ENTSTK 



LDX 
LDY 
STY 
DEY 
LDA 
STA 
LDA 
STA 

LDA 
BEQ 
STA 



GSBl 
GSB2 



GSB3 
GSB4 



LDY 
LDA 
BEG 
INY 
CPY 
BCC 



CURFCB 
ICDNOZ 
DCBDRV 

DBUFAL.Y 
ZDRVA 
DBUFAH,Y 
ZDRVA+1 

DRVTBL.Y 

DERRl 

DRVTYP 



TAY 

LDA DRVMDL.Y 

STA DRVMDL 

LDA DRVLBT.Y 

STA DRVLBT 

LDY FCBBUF.X 

DEY 

BPL SSBA 



#0 

SECTBL.Y 

GSB4 

#16 
GSBl 



JMP ERRNSB 

LDA DRVTYP 

LSR A 

BCS GSB5 



;INIT ERROR CODE 
rTO ZERO 
rSAVE FCB 



;GET CURRENT FCB 

;MOVE DRIVE NO 

rTO DCB 

;DEC FOR ACCESS TO TABLES 

;MOVE WRITE BUFFER 

;ADD TO ZERO PAGE PTR 



;GET DRIVE TYPE 
;BR IF NOT EXISTS 
rSAVE TYPE 

jMOVE MAX DATA LEN 
;AND LAST SECTOR BYTE 
;DISPL TO LAST OF 
; TABLES 



;GET SECTOR BUF * 

;DEC TO ACCESS TBL 

;BR IF ONE IS ALLOCATED 

;IF NON ALLOCATED 
;TRY TO FIND ONE 
;BR ONE FOUND 
;DEC TRY COUNT 

;BR MORE TO TRY 

;N0 SECTOR BUFFERS AVAIL 

; FOUND ONE IF 256 BYTES 
.•DRIVE NEEDED TO CONT 
;BR NOT 256 BYTES 



SETUP ROUTINE 



11:34 C8 


5312 


INY 




1135 C010 


5313 


CPY 


#16 


1137 B0F2 


5314 


BCS 


GSB3 


1139 B91913 


5315 


LDA 


SECTBL.Y 



;ELSE TRY NEXT CONTIG 
;TEST END OF BUFFERS 
:AND BR IF NO MORE 
;ELSE SEE IF ITS THREE 



92 



ATARI DOS 2.0S 



IIBC D0E8 
IIBEI 88 

IIBF A980 
llCl 991A13 

11C4 A980 
llC«i 991913 
11C9 98 
IICA 9D8813 
IICI) FE8813 

IIDH B93913 
1103 8547 
llDIi B94913 
11D8 8548 



IIDA 60 
11D13 4CCF12 



5316 
5317 
5318 ; 
5319 
5320 

5321 ; 

5322 GSB5 
5323 
5324 
5325 
5326 

5327 ; 

5328 SSBA 
5329 
5330 
5331 

5332 ; 

5333 ; 
5334 

5335 7 

5336 DERRl 



BNE GSB2 
DEY 



;BR NOT FREE 



LDA #S80 ; ALLOCATE SECOND OF 2 

STA SECTBL+l,y 

LDA #$80 ; ALLOCATE FIRST OR ONLY 

STA SECTBL.Y 

TYA 

STA FCBBUF,X ;POT BUF NO INTO FCB 

INC FCBBUF.X ;INC BUF NO SO NOT ZERO 

LDA SABUFL.y ;MOVE BUFFER ADDR 

STA ZSBA ;T0 ZERO PAGE PTR 

LDA SABUFH.Y 

STA ZSBA+1 



RTS 

JMP ERRDNO ;BAD DRIVE NO 



SETUP ROUTINE 



11D15 




5337 




.PAGE 








5338 


; 












5339 


; FREE 


SECTOR BUFFERS 








5340 


; 








IIDE 




5341 


FRESBUF = 


* 




IIDE 


BC8813 


5342 




LDY 


FCBBUF.X 


■GET BUF NO 


llEl 


F013 


5343 




BEO 


FSBR 


•BR IF NONE 


11E3 


88 


5344 




DEY 




;DEC FOR TBL ACCESS 


11E4 


A900 


5345 




LDA 


#0 


•FREE 


11E6 


9D8813 


5346 




STA 


FCBBUF , X 


;IN FCB 


11E9 


991913 


5347 




STA 


SECTBL.Y 


;AND TABLE 


llEC 


ADFE12 


5348 




LDA 


DRVTYP 


;IF 128 BYTES 


llEF 


4A 


5349 




LSR 


A 


; DRIVE 


11F0 


B004 


5350 




BCS 


FSBR 


;FREE ONLY ONE 


11F2 


4A 


5351 




LSR 


A 


;ELSE 


11F3 


991A13 


5352 




STA 


SECTBL+1,Y 


;FREE 2 


11F6 


60 


5353 
5354 


FSBR 

; 


RTS 







DATA SECTOR I/O 



11F7 




5355 




.PAGE "DATA SI 


:cn 


^OR I/O" 






5356 














5357 


; DSIO 


- DATA SECTOR 


I/O 






5358 














5359 


DSIO 








11F7 


48 


5360 




PHA 






SAVE ACU DATA 


11F8 


A547 


5361 




LDA 


ZSBA 




WRITE SECTOR BUF 


UFA 


8D0403 


5362 




STA 


DCBBUF 




ADR MOVED TO 


IIFD 


A548 


5363 




LDA 


ZSBA+1 




DCB 


IIFF 


8D0503 


5364 




STA 


DCBBUF+1 




1202 


68 


5365 
5366 


. 


PLA 




r RESTORE ACU 


1263 


AEFE12 


5367 




LDX 


DRVTYP 




1286 


206C07 


5368 




JSR 


BSIO 


;D0 THE l/O 


1229 


60 


5369 
5370 


; 


RTS 






WRITE DOS 












120A 




5371 




.PAGE "WRITE 


DOS" 






5372 


; 











93 



ATARI DOS 2.0S 







5373 


; WRTDOS - 


WRITE DOS 


TO DISK 






5374 


; 












5375 


WRTDOS 








120A 


BC8913 


5376 




LDY 


FCBCSN.X 


;MOVE START ADDR 


120D 


BD8A13 


5377 




LDA 


FCBCSN+1 , 


,X 


1210 


205312 


5378 




JSR 


SETDSO 


rWRITE SECTOR 


1213 


206712 


5379 




JSR 


WD0 


; WRITE DOS 


1216 


4CF012 


5380 
5381 
5382 


DELDOS 


JMP 


GREAT 




1219 


A900 


5383 
5384 


DDl 


LDA 


#0 


;SET FILE NOT EXISTS 


121B 


8D0E07 


5385 
5386 

5387 


WRTSCO 


STA 


DFSFLG 




121E 


A907 


5388 




LDA 


#FMSORG/256 ;MOVE FMS START 


1220 


8D0503 


5389 




STA 


DCBBUF+1 


jADDR TO DCB 


1223 


A900 


5390 




LDA 


#FMSORGS.255 


1225 


8D0403 


5391 
5392 


, 


STA 


DCBBUF 




1228 


A900 


5393 




LDA 


*0 


; CLEAR SECTOR NO TO 


122ft 


8D0A03 


5394 




STA 


DCBSEC 




122D 


8D0B03 


5395 
5396 


; 


STA 


DCBSEC+1 




1230 


EE0A03 


5397 


WRNBS 


INC 


DCBSEC 


;INC SECTOR NO 


1233 


A201 


5398 




LDX 


#1 


;GET DRIVE TYPE 


1235 


38 


5399 




SEC 






1235 


207207 


5400 
5401 
5402 


; 


JSR 


BSIOR 


;D0 THE WRITE 


1239 


18 


5403 




CLC 






123A 


AD0403 


5404 




LDA 


DCBBUF 


;INC SECT ADDR 


123:d 


6980 


5405 




ADC 


#128 




123? 


8D0403 


5406 




STA 


DCBBUF 




1242 


AD0503 


5407 




LDA 


DCBBUF+1 




1245 


6900 


5408 




ADC 


♦ 




1247 


8D0503 


5409 
5410 


. 


STA 


DCBBUF+1 




124A 


AD0A03 


5411 




LDA 


DCBSEC 


;TEST FOR WRITE 


1243 


CD0107 


5412 




CMP 


BRCNT 


;0F ALL BOOT SECTORS 


1253 


D0DE 


5413 
5414 


. 


BNE 


WRNBS 


;BR NOT ALL 


1252 


60 


5415 
5416 


, 


RTS 






1253 


8C0F07 


5417 


SETDSO 


STY 


DELINK 


;SET LINK START 


125i5 


8D1007 


5418 




STA 


DFLINK+1 




125'J 


ADFE12 


5419 




LDA 


DRVTYP 




125(: 


8D0E07 


5420 




STA 


DFSFLG 




125P 


ACF812 


5421 




LDY 


DRVMDL 




WRITE DOS 













1262 8C1107 5422 

1265 D0B4 5423 

5424 



STY BLDISP 
BNE DDl 



;G0 WRITE SECTOR 



WRITE DOS 












1267 


5425 




.PAGE 


II 


1267 AD1207 


5426 


WD0 


LDA 


DFLADR 


;MOVE PILE START ADDR 


126A 8543 


5427 




STA 


ZBUFP 


;TO ZBUFP 


126C AD1307 


5428 




LDA 


DFLADR+1 




126F 8544 


5429 
5430 


, 


STA 


ZBUFP+1 




1271 A000 


5431 


WDl 


LDY 


#0 


;MOVE 125 


1273 B143 


5432 


WD 2 


LDA 


( ZBUFP ),Y 


.•BYTES OF DOS 



94 



ATARI DOS 2.0S 



12-'5 


9147 


5433 




STA 


(ZSBA),Y 


1277 


C8 


5434 




INY 




1278 


CCF812 


5435 




cpy 


DRVMDL 


127B 


90F6 


5436 




BCC 


WD 2 


127D 


98 


5437 




TYA 




127E 


9D8713 


5438 
5439 


, 


STA 


FCBDLN.X 


12131 


205707 


5440 




JSR 


INCBA 


12:34 


CD0D07 


5441 




CMP 


SASA+1 


1237 


900B 


5442 




BCC 


WD 3 


12:39 


D00F 


5443 




BNE 


WD4 


12:3B 


A543 


5444 




LDA 


ZBUFP 


12:3D 


CD0C07 


5445 




CMP 


SASA 


1230 


9002 


5446 




BCC 


WD 3 


1292 


D006 


5447 
5448 


, 


BNE 


WD4 


1294 


20940F 


5449 


WD 3 


JSR 


WRTNXS 


1297 


4C7112 


5450 
5451 


. 


JMP 


WDl 


129A 


60 


5452 


WD4 


RTS 








5453 


; AND 


RETURN 






5454 


r 







;T0 SECTOR BUFFER 



;SET DATA LEN 

INC ZBUFP BY 125 
IF NOT END OR 
PAST END OF DOS 
THEN WRTNXS 
ELSE 
DONE 



rWRITE NEXT SECTOR 



; RETURN, CLOSE WILL WRITE 
FINAL SECTOR 



TEST DOS FILE NAME 



129B 



129B A00B 
129D B95813 
12A0 D9A812 
12A3 D003 
12A5 88 
12A6 D0F5 
12A8 60 

12A9 44 

12AA 4F 

12AB 53 

12 AC 20 

1::AD 20 

12AE 20 

1:;AF 20 

i:!B0 20 
i:iBi 53 
i;:b2 59 

i;!B3 53 
12B4 20 



5455 

5456 ; 

5457 ; TSTDC 

5458 ; 

5459 TSTDOS 
5460 

5461 TDFl 

5462 

5463 

5464 

5465 

5466 TDFR 

5467 ; 

5468 DFN 



.PAGE "TEST DOS FILE NAME" 



TEST FOR DOS SYS FILE NAME; 



LDY 
LDA 
CMP 
BNE 
DEY 
BNE 
RTS 



#11 
FNAME- 
DFN-1, 
TDFR 

TDFl 



.BYTE "DOS 



;LOOK AT 12 CHARS 
1,Y rTEST DECODE FILENAME CHAR 
Y ;WITH DOS FILENAME CHAR 

rBR NOT MATCH 

rBR IF MORE, ELSE RTN EQ 



SYS " 









5469 














5470 


; ERROR ROUTINES 








5471 










!B5 


E649 


5472 


ERDBAD 


INC 


ERRNO 




!B7 


E649 


5473 


ERAPO 


INC 


ERRNO 




!B9 


E649 


5474 


ERRPOT 


INC 


ERRNO 




IBB 


E649 


5475 


ERFNF 


INC 


ERRNO 




iBD 


E649 


5476 


ERDFULL INC 


ERRNO 




IBF 


E649 


5477 


ERDVDC 


INC 


ERRNO 




!C1 


E649 


5478 


ERFLOCK INC 


ERRNO 




!C3 


E649 


5479 


ERRPDL 


INC 


ERRNO 




!C5 


E649 


5480 


ERRFN 


INC 


ERRNO 




!C7 


E649 


5481 


ERFNMM 


INC 


ERRNO 




!C9 


E649 


5482 


ERRSYS 


INC 


ERRNO 



;BAD SECTOR AT FORMAT TIME 
; ATTEMPT APPEND TO OLD TYPE 

FILE 
; POINT INVALID 
;FILE NOT FOUND 
; DIRECTORY FULL 
; DEVICE COMMAND INVALID 
;FILE LOCKED 
.•POINT DATA LENGTH 
;FILE NAME ERROR 
;FILE NUMBER MISMATCH 
r FATAL SYS DATA l/O ERROR 



95 



ATARI DOS 2.0S 



12CB 


E649 


5483 


ERRNSA 


INC 


ERRNO 


i2cn 


E649 


5484 


ERRNSB 


INC 


ERRNO 


12CF 


E649 


5485 
5486 


ERRDNO 


INC 


ERRNO 


12D1 


A549 


5487 




LDA 


ERRNO 


12D3 


AE0113 


5488 


RETURN 


LDX 


CURFCB 


12D6 


9D4303 


5489 




STA 


ICSTA.X 


12D9 


AE0013 


5490 




LDX 


ENTSTK 


12DC 


9A 


5491 




TXS 




12DD 


AE0113 


5492 




LDX 


CURFCB 


12E0 


A8 


5493 




TAY 




12E1 


AD0813 


5494 




LDA 


SVDBYT 



;N0 SECTOR AVAIL 

;N0 SECTOR BUFFERS AVAIL 

; DRIVE NO ERROR 

;GET ERROR NUMBER 
;GET CUR FCB NO 
;PUT IN FCB 
;GET ENTRY STACK PTR 
;AND RESTORE 



;GET SAVED DATA BYTE 



TEST DOS FILE NAME 



12E4 


60 


5495 
5496 


. 


RTS 






12E5 


AD0303 


5497 


ERRIO 


LDA 


DCBSTA 


;GET I/O ERROR CODE 


12E8 


30E9 


5498 
5499 


, 


BMI 


RETURN 




12EA 


AE0113 


5500 


FGREAT 


LDX 


CURFCB 




12ED 


20DE11 


5501 




JSR 


FRESBUF 


rFREE SECTOR BUFFER 


12F0 


A901 


5502 


GREAT 


LDA 


#01 


;SET ALL OK 


12F2 


D0DF 


5503 




BNE 


RETURN 




12F4 


A988 


5504 


ERREOF 


LDA 


#588 


rSET EOF CODE 


12F6 


30DB 


5505 
5506 


. 


BMI 


RETURN 





MISC STORAGE 



12F8 




5507 




.PAGE "MI 






5508 












5509 


; MISC 


NON 


ZERO 






5510 








12Ffl 


00 


5511 


DRVMDL 


.BYTE 


12F9 


7D 


5512 




.BYTE 125 


12FA 


FD 


5513 




.BYTE 253 






5514 


; 






12FI! 


00 


5515 


DRVLBT 


.BYTE 


12FC 


7F 


5516 




.BYTE 127 


i2Fn 


FF 


5517 




.BYTE 255 


i2Fi: 




5518 


DRVTYP 


*= 


*+l 


i2Fr 




5519 


RETRY 


*= 


*+l 


130CI 




5520 


ENTSTK 


*= 


*+l 


1301 




5521 


CURFCB 


* — 


*+l 


130:; 




5522 


DHOLES 


*— 


*+l 


130;: 




5523 


DHOLED 


*= 


*+l 


130A 




5524 


DHFNUM 


* — 


*+l 


1305 




5525 


CDIRD 


*= 


*+l 


1306 




5526 


CDIRS 


*= 


*+l 


1307 




5527 


SFNUM 


*= 


*+l 


130EI 




5528 


SVDBYT 


*= 


*+l 


1309' 




5529 


SVDl 


*— 


*+l 


130A 




5530 


SVD2 


*— 


*+l 


130E; 




5531 
5532 


SVD3 
EXTSW 


*= 


*+l 


130C 




5533 


TEMPI 


*— 


*+l 


13011 




5534 


TEMP2 


*= 


*+l 


13011 




5535 


TEMP 3 


*= 


*+l 


130F 




5536 


TEMP4 


*= 


*+l 


i3iei 




5537 
5538 


BURTYP 


*ss 


*+l 


1311 




5539 


DRVTBL 


It- 


*+8 


1319 




5540 


SECTBL 


It— 


*+16 


1329 




5541 


DBUFAL 


*— 


*+8 


1331 




5542 


DBUFAH 


*= 


*+8 



MAX DATA LEN 
128 BYTE SECTOR 
256 BYTE SECTOR 

rDISPL TO LAST SECTOR BYTE 

,•128 BYTE SECTOR 

;256 BYTE SECTOR 

; DRIVE TYPE 

;l/0 RETRY COUNTER 

; ENTRY STACK LEVEL 

.■CURRENT FCB ( lOCB ALSO) 

;DIR HOLE SECTOR 

;DIR HOLE DISPL 

DIR HOLE FILE NO 

;CURRENT DIR DISPL 

r CURRENT DIR SECTOR 

;FILE NUMBER 

; SAVED OUTPUT DATA BYTE 

rSAVE DATA BYTES 

.•FOR WRITE BURST 



; TEMPI 
;TEMP2 
;TEMP3 
;TEMP4 
; BURST I/O TYPE 

DRIVE TABLE 



VTOC BUFFER 
PTR FOR DRIVE N 



96 



ATARI DOS 2.0S 



1339 


5543 


SABUFL 


*s 


*+16 


; SECTOR BUFFER 


1349 


5544 


SABUFH 


*s 


*+16 


jFOR SECTOR N 


1359 


5545 


FNAME 


*s 


*+12 


;FILE NAME 


1365 


5 546 
5547 


AFNAME 


*— 


*+12 


jAUXILLARY FILE NAME 


1371 


5548 
5549 


MDRV 


*= 


*+l 


jMAX DR NO 


1372 


5550 


Z 


= 


* 


;PUT ON SAME BOUNDRY AS 
PRODUCTION 


1372 


5551 




*s 


$1381 


;VERSION 



F]:LE CONTROL BLOCKS 



13181 


5552 




.PAGE "FILE CONTROL BLOCKS" 




5553 


• 










5554 


; FILE 


CONTROL BLOCK 






5555 


; ONE FILE 


CONTROL BLOCK IS USED FOR EACH 




5556 


; OPEN 


FILE. THE RELATIVE FCB USED 




5557 


; RELATES 


DIRECTLY TO THE lOCB * 




5558 


r THAT 


OPENED THE FILE. 


THUS THERE ARE 




5559 


; 8 FCBS. 


THE FCB ARE 


(CONVIENTLY) 




5560 


; THE SAME 


SIZE AS lOCBS. EACH FCB 




5561 


; CONTAINS 


ALL THE INFORMATION REQUIRED 




5562 


; TO CONTROL THE PROCESSING ON AN 




5563 


r OPEN 


FILE 






5564 


; 










5565 


FCB 








1381 


5566 


FCBFNO 


*= 


*+l ; 


FILE # LEFT JUSTIFIED 


1382 


5567 


FCBOTC 


*= 


*+l 


OPEN TYPE CODE 


1383 


5568 




*= 


*+l ; 


SPARE 


1384 


5569 


FCBSLT 


*— 


*+i ; 


FLAG FOR NEW SECTOR LEN 1 


1385 


5570 


FCBFLG 


*= 


*+l 


WORKING FLAG 


1386 


5571 


FCBMLN 


It- 


*+l 


MAX SECTOR DATA LEN 


1387 


5572 


FCBDLN 


It— 


*+l 


CUR SECTOR BUF DATA LEN 


1388 


5573 


FCBBUF 


*— 


*+l 


SECTOR BUF NO 


1389 


5574 


FCBCSN 


*= 


*+2 


CUR SECTOR # 


138B 


5575 


FCBLSN 


*— 


*+2 


LINK/ALLOCATE SECTOR # 


138D 


5576 
5577 


FCBSSN 
FCBCRS 


*— 


*+2 


CUR FILE RELATIVE SECTOR 


138F 


5578 


FCBCNT 


*= 


*+2 


SECTOR COUNT 


0310 


5579 
5580 


FCBLEN 


- 


*-FCB 


FCB LEN 


1391 


5581 
5582 




* = 


FCBLEN*7+* 


; ALLOCATE 7 MORE FCBS 




5583 


r OPEN 


CODE BITS 






5584 


; USED 


IN 


lOCB AUXl 






5585 


; - AND FCBOTC 






5586 










0004 


5587 


OPIN 


= 


$04 


-INPUT 


0008 


5 588 


OPOUT 


= 


$08 


•OUTPUT 


0002 


5589 


OPDIR 


= 


$02 


jLIST DIRECTORY 


0001 


5590 
5591 


OPAPND 


= 


$01 


; APPEND 


0080 


5592 


FCBFAS 


= 


$80 


; FCBFLG - ACQ SECTORS 


0040 


5593 


FCBFSM 


= 


$40 


; FCBFLG - SECTOR MODIFIED 


FILE 


DIRECTORY 










1401 


5594 




.PAGE "FILE DIR 


ECTORY" 




5595 


• 










5596 


,- DISK 


FILE DIRECTORY 






5597 


; THE 


FILE DIRECTORY 


CCUPIES 8 




5598 


;CONSECTUIVE SECTORS S 


TARTING AT THE 




5599 


,• CENTRAL 


SECTOR+1 . E 


ACH FILE DIRECTORY 




5600 


; SECTOR CONTAINS 8 EN 


[TRIES . THERE 




5601 


; IS 1 


ENTRY FOR EACH 


NAMED FILE. THE 



97 



ATARI DOS 2.0S 



0001 

0003 
0005 
000D 

0011?' 



000(1 
008 ei 

004(1 

0001 

0020 

000; 



1401 



5602 
5603 
5604 
5605 
5606 
5607 
5608 
5609 
5610 
5611 
5612 
5613 
5614 
5615 
5616 
5617 
5618 
5619 
5620 
5621 
5622 
5623 
5624 
5625 
5626 

5627 
5628 
5629 



THERE ARE A TOTAL OF 64 NAMED FILES 
PER VOLUME 

THE FILE NUMBER IS USED THROUGH THE 
THE SYSTEM IS THE RELATIVE (TO ONE) 
FILE DIRECTORY ENTRY NUMBER. 

THE EQUATES BELOW ARE FOR A SINCE NAMED 
FILE ENTRY 



DFDFLl = 

DFDCNT = 

DFDSSN = 

DFDPFN = 

DFDXFN = 

DFDELN = 



1 

3 

5 

13 

16 



;FLAG1 (1) 

; SECTOR COUNTER (LOW) 
; START SECTOR NO (2) 
; PRIMARY FILE NAME (8) 
rEXTENDED FILE NAME (4) 
; ENTRY LENGTH 



DFDFLl VALUE EQUATES 



DFDEUU 
DFDEDE 
DFDINU 
DFEXJUT 
DFDLOC 
DFDNLD 



FILDIR *= 





$80 

$40 

$01 

$20 

$02 



*+256 



; ENTRY UNUSED 
r ENTRY DELETED 
.•ENTRY IN USE 
;FILE OPEN FOR OUTPUT 
.•ENTRY LOCKED 

;FILE HAS NEW TYPE SECTOR LEN 
BYTE 

r RESUME FILE DIR SPACE 



VOLUME DIRECTORY 



1501 



0000 



0001 
0003 



0005 
000A 



5630 
5631 
5632 
5633 
5634 
5635 
5636 
5637 
5638 
5639 
5640 
5641 
5642 
5643 
5644 
5645 
5646 
5647 
5648 
5649 
5650 
5651 
5652 
5653 
5654 
5655 
5656 
5657 



.PAGE "VOLUME DIRECTORY" 

DISK VOLUME DIRECTORY 

THE VOLUME DIRECTORY OCCUPIES THE CENTRAL 

VOLUME SECTOR. THE VOLUME DIRECTORY 

CONTAINS INFORMATION PERTAINING TO 

THE ENTIRE DISKETTE VOLUME. 

THE LABELS BELOW, MAP THE VOLUME 
DIRECTORY SECTOR. 



DVDTCD 



; VOLUME DIRECTORY TYEP CODE )1) 



USED TO DELINATE MAJOR (1) 
FMS SYSTEM FORMAT CHANGES 



DVDMSN = 
DVDNSA = 



DVDWRQ 
DVDSMP 



5 
10 



;MAX SECTOR NUMBER (1) 
rNO SECTORS AVAIL 

rWRITE REQUIRED 
.•SECTOR MAP START 



EACH BIT REPRESENTS A SECTOR 

IF THE BIT IS ON THEN THE SECTOR 

IS FREE AND AVAILABLE. IF THE 

BIT IS OFF, THE SECTOR IS IN 

USE OR BAD. THE MOST SIGNIFICANT 

BIT OF THE FIRST BYTE IS SECTOR ZERO. 



END OF FMS 



1501 



1501 
1501 



5658 

5659 ; 

5660 ENDFMS = 

60 . END 



PAGE "END OF FMS" 



98 



ATARI DOS 2.0S 



EtID OF FMS 














=0700 


FMSORG 


=0043 


FMSZPG 


=0340 


lOCBORG 


=0003 


LMASK 


=£1300 


DCBORG 


=E453 


DHADR 


=009B 


EOL 


=031A 


DEVTAB 


=CI020 


ZICB 


=02E7 


LMADR 


=1540 


DUPINIT 


=0102 


STAR 


=00DF 


OSBTM 


=0246 


DSKTIM 


=000F 


TIMOUT 


0340 


lOCB 


0340 


ICHID 


0341 


ICDNO 


0342 


ICCOM 


0343 


ICSTA 


0344 


ICBAL 


0345 


ICBAH 


0346 


ICPUT 


0348 


ICBLL 


0349 


ICBLH 


034A 


ICAUXl 


034B 


ICAUX2 


034C 


ICAUX3 


034D 


ICAUX4 


034E 


ICAUX5 


034F 


ICAUX6 


=0010 


ICLEN 


=0001 


ICOIN 


=0002 


ICOOUT 


=0003 


ICIO 


=0004 


ICGBR 


=0005 


ICGTR 


=0006 


ICGBC 


=0007 


ICGTC 


=0008 


ICPBR 


=£1009 


ICPTR 


=000A 


ICPBC 


=000B 


ICPTC 


=000C 


ICCLOSE 


=000D 


ICSTAT 


=000E 


ICDDC 


=000E 


ICMAX 


=000F 


ICFREE 


=£1001 


ICSOK 


=0002 


ICSTR 


=0003 


ICSEOF 


=0080 


ICSBRK 


=0081 


ICSDNR 


=0082 


ICSNEP 


=0083 


ICSDER 


=0084 


ICSIVC 


=0085 


ICSNOP 


=0086 


ICSIVN 


=0087 


ICSWPC 


=0021 


ICDNOZ 


=0028 


ICBLLZ 


=0029 


ICBLHZ 


=0024 


ICBALZ 


=0025 


ICBAHZ 


=0022 


ICCOMZ 


=0026 


ICPUTZ 


0300 


DCB 


0300 


DCBSBI 


0301 


DCBDRV 


0302 


DCBCMD 


0303 


DCBSTA 


0304 


DCBBUF 


0306 


DCBTO 


0308 


DCBCNT 


030A 


DCBSEC 


=0052 


DCBCRS 


=0050 


DCBCWS 


=005 3 


DCBCST 


=0021 


DCBCFD 


=0001 


DCBSOK 


=0081 


DCBDNR 


=0082 


DCBCNR 


=0083 


DCBDER 


=0084 


DCBIVC 


=£1087 


DCBWPR 


0043 


ZBUFP 


0045 


ZDRVA 


0047 


ZSBA 


0049 


errno 


0700 


BFLG 


0701 


BRCNT 


0702 


BLDADR 


0704 


BINTADR 


0706 


BCONT 


0714 


XBCONT 


0709 


SABYTE 


070A 


DRVBYT 


070B 


SAFBFW 


070C 


SASA 


=1501 


ENDFMS 


070E 


DFSFLG 


070F 


DFLINK 


0711 


BLDISP 


0712 


DFLADR 


07CB 


DFMSDH 


074F 


BFAIL 


072F 


XBCl 


=076C 


BSIO 


0753 


BGOOD 


0757 


INCBA 


0754 


XBRTN 


0772 


BSIOR 


077C 


DSIOl 


0786 


DSI02 


12FF 


RETRY 


079C 


DSI03 


07A2 


DSI04 


07C4 


DSI05 


07BE 


STRTYP 


1301 


CURFCB 


08AB 


DFMOPN 


0B15 


DFMCLS 


=0ABF 


DFMGET 


09CC 


DFMPUT 


0B01 


DFMSTA 


0BA7 


DFMDDC 


=07E0 


DINIT 


130C 


TEMPI 


07P2 


DIA 


130D 


TEMP2 


0807 


DIHAVE 


1311 


DRVTBL 


1329 


DBUFAL 


1331 


DBUFAH 


083D 


DIDDEC 


=0005 


DVDWRQ 


0823 


DI256 


0870 


DINCBP 


0845 


DINXTS 


084B 


DISETS 


1319 


sectbl 


08 5E 


DISNI 


1339 


SABUFL 


1349 


SABUFH 


=087E 


CLRFCB 


0882 


CFCBX 


1381 


FCB 


088A 


ADIl 


089B 


ADI2 


1164 


SETUP 


0E9E 


FNDCODE 


1382 


FCBOTC 


=0002 


OPDIR 


08BE 


OPNl 


0DAD 


LISTDIR 


0F21 


SPDIR 


=0004 


OPIN 


=08D8 


DFOIN 


=0008 


OPOUT 


=0911 


DFOOUT 


=08DD 


DFOUPD 


=0001 


OPAPND 


=fl8EC 


DFOAPN 


12BF 


ERDVDC 


08E9 


OPNERl 


=08E3 


DFOUI 


0CAC 


TSTLOCK 


09AE 


DFRDSU 


12F0 


GREAT 


12BB 


ERFNF 


1305 


CDIRD 


1401 


FILDIR 


=0000 


DFDFLl 


=0002 


DFDNLD 


090E 


APOER 


10BF 


OPVTOC 


].106 


GETSECTOR 


138D 


FCBSSN 


13aB 


FCBLSN 


=097C 


DHF0X2 


].2B7 


ERAPO 


=091D 


DFOXl 


0C53 


XDEL0 


=0948 


OPNIA 


1302 


DHOLES 


0992 


0PNER2 


1306 


CDIRS 


10eE 


RDDIR 


:.303 


DHOLE D 


1304 


DHFNUM 


1307 


SFNUM 


093E 


OPNIB 


=0005 


DFDPFN 


=0003 


DFDSSN 


=0040 


DFDINU 


=0001 


DFDOUT 


=0001 


DFDCNT 


0966 


0PN2 


1359 


FNAME 


=0970 


0PN2A 


1071 


WRTDIR 


=0995 


SETFCB 


0FE2 


WRTN6 


0982 


0PN3 


=0080 


FCBFAS 


1385 


FCBFLG 


129B 


TSTDOS 


=098F 


DHF0X3 


].20A 


WRTDOS 


12BD 


ERDFULL 


099A 


OPNFl 


1381 


FCBFNO 


1387 


FCBDLN 


138F 


FCBCNT 


1384 


FCBSLT 


=1017 


RDNSO 


1308 


SVDBYT 


1300 


ENTSTK 


09E5 


FRMCIO 


0A19 


PUTER 


1386 


FCBMLN 


0A06 


PUTl 


0F94 


WRTNXS 


0A1C 


PEOF 


OAIF 


WTBUR 


=0040 


FCBFSM 


12F4 


ERREOF 


0A4A 


NOBURST 


0A28 


TBURST 


0A26 


RTBUR 


1310 


BURTYP 


=0AAE 


TBLEN 


()A3E 


NXTBUR 


0A4C 


WRBUR 


100F 


RDNXTS 


0A7B 


BBINC 


=I)A9D 


BUREOF 


12F8 


DRVMDL 


1309 


SVDl 


130A 


SVD2 


:L30B 


SVD3 


1388 


FCBBUF 


11D0 


SSBA 


0AAC 


BURST 


:l2pe 


DRVTYP 


0AB9 


TBL256 


0ACC 


GETl 


0DB9 


GDCHAR 


UADF 


GET 2 


=0ADC 


GEOF 


=0AEA 


EFLOOK 


0AFE 


GET3 


:L2D3 


RETURN 


0B12 


SFNF 


0B6D 


CLDONE 


=0B75 


CLUPDT 


IJFAB 


WRTLSEC 


=0B80 


RRDIR 


0B50 


CLOUT 


0B3C 


APPl 



99 



ATi\RI DOS 2.0S 



0FB3 


WRTN2 


1095 


WRTVTOC 


12EA 


FGREAT 


0FF8 


WRCSIO 


0B9B 


FNSHFT 


0B9D 


FNSHFl 


0B9F 


FNSHF2 


0BD6 


XFV 


■0027 


MAXDDC 


0BD3 


DVDCER 


0BC5 


DVDCVT 


0BD9 


XRENAME 


0C32 


XDELETE 


0C7C 


XLOCK 


0C83 


XONLOCK 


0CBA 


XPOINT 


0D03 


XNOTE 


0D18 


XFORMAT 


0BE7 


XRNl 


0BF2 


XRNl A 


1219 


DELDOS 


0EB4 


FNDCNX 


0C0C 


XRNIB 


1253 


SETDSO 


0C11 


XRN2 


0C1B 


XRN3 


0F31 


CSFDIR 


0C79 


DFNF 


=0C3A 


XDELX 


0C45 


XDELY 


0C45 


XDEL3 


0C56 


XDELl 


=008 C!l 


DFDEDE 


=0C6C 


XDEL2A 


0C67 


XDEL2 


=0C72 


XDEL4 


10C5 


FRESECT 


=0020 


DFDLOC 


130F 


TEMP4 


0C88 


XLCOM 


0C93 


XLCl 


0CB7 


TLF 


12C1 


ERFLOCK 


0D00 


PERRl 


1389 


FCBCSN 


0CCF 


XPl 


0CED 


XP2 


=0CDC 


XPl A 


=0CF7 


XPERR 


0CFA 


XP3 


12C3 


ERRPDL 


12B9 


ERRPOT 


0D52 


XF0 


0D4F 


XFERR 


=0D3D 


TSTFMT 


0D4C 


XFBAD 


12B5 


ERDBAD 


0D55 


XFl 


=000A 


DVDSMP 


0D76 


XF2 


0D94 


XF3 


0D9F 


XF4 


0DE3 


LDENTl 


0DE9 


LDCNT 


0E11 


LDDONE 


0DD6 


GDCRTN 


0DD9 


LDENT 


0E21 


FDENT 


108B 


RDVTOC 


=0003 


DVDNSA 


0E57 


CVDX 


=000D 


FSCML 


0DFD 


MVFSCM 


0E14 


FSCM 


0E67 


CVDY 


0E35 


LDl 


0E3B 


LD2 


0E71 


CVDIGIT 


0E8D 


STDIGIT 


130E 


TEMP3 


0E76 


CVDl 


0EAA 


FD0A 


0F07 


FNDERR 


0EB3 


FD0B 


0EB8 


FD0 


130C 


EXTSW 


0EC3 


FDl 


0ED5 


FD3 


0ECR 


FD2 


0F0A 


FDSCHAR 


0F03 


FDEND 


0EE5 


FD4 


0EFD 


FD6 


0EF1 


FD5 


12C5 


ERRFN 


0F1B 


FDSC2 


0F15 


FDSCl 


=0010 


DFDELN 


0F4D 


SFD2 


0F48 


SFDl 


0F90 


SDRTN 


0F73 


SPDSH 


0F5E 


SFD3 


0F6A 


SFD4 


0FBA 


SFDSHl 


0FA8 


WRTNl 


0FA5 


WRUl 


0FC9 


WRNERR 


0FAE 


WRTLSl 


12FB 


DRVLBT 


0FDA 


WRTN5 


1002 


MVLSN 


0FF6 


WRNRTS 


0FF9 


RWCSIO 


11F7 


DSIO 


1021 


RDNSl 


105P 


RDIOER 


=1062 


RDFNMM 


1054 


RDNS3 


1051 


RONS 2 


12E5 


ERRIO 


106C 


RDDELE 


12C7 


ERFNMM 


1072 


DIRIO 


10AB 


DSYSIO 


1092 


RDVGO 


109C 


VTIO 


1095 


WRVTOC 


10AC 


DSYSIA 


10B5 


DSIOER 


10BC 


DEAD 


12C9 


ERRSYS 


=1105 


FSRTS 


10D1 


FSl 


10DD 


FS2 


10E5 


FS3 


1108 


GSl 


1161 


GSERR 


112D 


GS2 


1134 


GS3 


1148 


GS4 


12CB 


ERRNSA 


IIDB 


DERRl 


llAl 


GSBl 


llAE 


GSB4 


11A6 


GSB2 


llAB 


GSB3 


12CD 


ERRNSB 


11C4 


GSB5 


12CF 


ERRDNO 


=11DE 


FRESBUF 


11F6 


FSBR 


1267 


WD0 


121B 


DDl 


121E 


WRTSCO 


1230 


WRNBS 


1271 


WDl 


1273 


WD 2 


1294 


WD 3 


129A 


WP4 


129D 


TDFl 


12A9 


DFN 


12A8 


TDFR 


1365 


AFNAME 


1371 


MDRV 


=1372 


Z 


138F 


FCBCRS 


=0010 


FCBLEN 


=000D 


DFDXFN 


=0000 


DFDEUU 


=0000 


DVDTCD 


=0001 


DVDMSN 



100 



v^ 






^ 



Appendix A 

AN 
INTERMEDIATE 
USER'S GUIDE 
TO THIS BOOK 



If you are familiar with machine language, commented source code, 
and hexadecimal numbers, you probably won't need to read this 
appendix. On the other hand, if you don't know or are new to machine 
language - perhaps some of the information here will help. 

A knowledge of machine language is important to grasping the 
sense of the DOS since it is written in machine language. However, 
we will briefly cover some of the fundamentals, as they relate to the 
book, in the hope that this might be a starting point. One of the 
functions of this book is to reveal the inner workings of Atari DOS. A 
benerit of knowing how it works is that you are able to change it to 
suit yourself, to customize it. 

First we'll examine the meaning of the various fields of information 
whicli are in the source code (page 59 on). Then, after a brief look at 
how ro deal with hexadecimal numbers, we can make a modification 
to D(DS step-by-step to show how it's done. 

The book is divided into two sections: roughly the first half is a 
series of descriptions of the major subroutines of the disk operating 
system. The latter half is a commented source code of the DOS. In order 
to better understand what you can accomplish with all this information, 
we can set up a problem and solve it using the book. 

Whoit's "Commented Source Code"? 

We'll change the DOS so that we could type in a disk command using 
lowercase letters. Unfortunately, the D: must be in uppercase, the 
program which makes this decision is in ROM and we can't get at it 
and change it. The rest of the command can be in lowercase, though, 
after we make our change to the DOS in RAM. After fixing it, any 
routine that uses the disk will accept lowercase as in D: open. 



102 



APPENDIX A 



Before getting into the details of the modification there is some 
important preliminary information. What, for example, is "commented 
source code?" 

Machine language differs in several respects from BASIC. When 
you write a program in BASIC, you never see how it looks to the 
computer. Instead you see something like this: 

10 FORI = lTO100 
20 NEXT 1 

This delay loop just creates a brief pause in a program. If you 
RUN the above, the computer handles the problem of translating the 
BASIC words into machine language. Anything the computer does 
must be translated into machine language (ML). Translating (or 
interpreting) a BASIC program takes place during the RUN of the 
program - that's why BASIC is so slow compared to ML. 

By contrast, ML is translated before it is RUN. Programming ML 
is done in two stages: 1. writing the source code and then 2. assembling 
it into object code. The computer does most of the drudgery of this 
because most ML is written by using a program called an assembler 
which handles many of the details. Some assemblers are so complex 
ttiat using them can seem almost like programming in BASIC. 

Here is how you might program the above example delay loop 
when using an assembler: 

1 000 LDY #64 ; SET COUNTER TO 1 00 

1001 LOOP DEY 

1002 BNE LOOP 

Probably the most peculiar thing about this, to the beginner, is 
how 64 stands for 100 (it's hex, we'll get to it in a minute). The line 
nambers could be BASIC, but the instructions are 6502 mnemonics 
(memory aids). LDY means to load the Y register with 100 (decimal). 
The next line is named (labelled) "loop" because assemblers don't say 
CiOTO 1001. Instead, they use convenient names. In any event, the 
Y register is decremented by DEY, it's lowered by one. So each time 
the program cycles through the LOOP address, it will lower the counter 
one. Finally, the instruction at 1002 says. Branch if Not Equal (to 
zero). In other words, GOTO LOOP if Y hasn't yet counted down to 
zero. When Y reaches zero, the program will continue on, following 
whatever instruction is in line 1003. 

After the above program is written, though, it still cannot be 
BUN. There is the second step, the creation of object code 
((Executable), the assembly process. 

You tell the assembler to assemble this program. The result of 

103 



APIPENDIXA 



that is an additional two "fields" (zones). Above, we have five fields: 
line number, label, mnemonic (instruction), operand (the #64), and 
a comment field which is the equivalent of BASIC REM statements. 
There will soon be a total of seven fields. 

After assembly, the two new fields are the addresses and the 
object code (expressed as hex bytes). By the way, BASIC always 
assigns its programs a starting address in memory, but, in ML, the 
programmer must make this known to the assembler. It's not the 
computer's decision. Assume the computer were told to assemble the 
above example at address $2000 (this would be 8192, in decimal). 
The dollar sign means that a number is a hex number. The labels, 
mnemonics, and operands would be translated into object code and 
put into the computer's memory. As you'll see in the second half of 
this iDook, a printout of completed assembly looks like this: 

200C AOOO 1000 LDY #64 ; SET COUNTER TO 100 

2002 88 1001 LOOP DEY 

2003 DOFF 1002 BNE LOOP 

Hex 

Before concluding this brief overview of some fundamentals of machine 
language, we should explain how to read the numbers in the source 
code listings. 

100 DIM H$(23) ,N$(9) :OPEN#1,4,0,"K:" 

130 GRAPHICS 

140 PRINT "PLEASE CHOOSE: 

150 PRINT "1 - Input HEX & get decimal back 

n 

160 PRINT "2 - Input DECIMAL to get hex bac 

k." 
170 PRINT:PRINT "==>"; :GET#1 ,K 
180 IF K<49 OR K>50 THEN 170 
190 PRINT CHR$(K):ON K-48 GOTO 300,400 
300 H$="@ABCDEFGHI! ! ! ! ! ! IJKLMNO" 
310 PRINT "HEX";:INPUT N$:N=0 
320 FOR 1=1 TO LEN(N$) 

330 N=N*16+ASC(H$(ASC(N$(I))-47))-64:NEXT I 

350 PRINT "$";N$;"=";N:PRINT:PRINT:GOTO 140 

400 H$="0123456789ABCDEF" 

410 PRINT "DECIMAL"; : INPUT N:M=4096 

4 20 PRINT N;"=$"; 

104 



APPENDIX A 



430 FOR 1=1 TO 4:J=INT{N/M) 

440 PRINT H$(J+1,J+1) ; :N=N-M*J:M=M/16 

450 NEXT I:PRINT:PRINT:GOTO 140 

This program will turn a decimal number into hex or vice versa. 
Hexadecimal is a base 16 number system, where decimal is base ten. 
This means that you count from zero to fifteen before going to the 
n(!xt column. For example, you count up zero one two. . .until you 
reach nine in decimal. Then you go to the next column and have a 
one-zero (10) to show that there is one in the "ten's column" and zero 
ir the "one's column. " 

In hex, what was a "ten's column" becomes a "sixteen's column." 
In other words, the symbol "10" means that there is one sixteen and 
zero "ones." So, the decimal number 17 would be written in hex, as 
$11 (one sixteen plus one one). The decimal number 15 would, in 
hex, be $0F. After nine, we run out of digits, so the first few letters of 
the alphabet are used: A= 10, B= 11, C= 12, D= 13, E= 14, and 
F=15. 

This explains how to "read" hex numbers if you don't want the 
pirogram above to do it for you. The number $64 is decimal 100 because 
there are six 16's and four one's. 6 X 16 4- 4 = 100. 

Addresses can be larger than two digits, up to a maximum of 
four. You might see an address such as $1 1F7 in the listings. The third 
column is the 256's and the fourth column is the 4096's. So to find 
out what this address is in decimal, you can multiply 7X1, 15X16, 
1 X 256, and 1 X 4096. And add them all together. 

A quicker way is to find out the first two, (15x16 + 7 = 247) and 
tlien multiply the second two by 256. It comes out the same. The 
second two would be $ 1 1 ( 1 7 in decimal) so 1 7 x 256 + 247 = 4599. It 
might be easier to just use the BASIC program to make the translations 
until hex becomes more familiar. 

Making A Modification 

Now that you have the entire source listing of EXDS 2. OS, you can 
customize it to fit your needs. 

You may have felt restricted by the limitations on file names. A 
file name can consist of eleven characters: up to eight characters plus 
an optional three-character extension. The first character must be 
from A-Z; subsequent characters can be from A-Z or 0-9. That's it. 
f >]o punctuation. No imbedded spaces. No lowercase. 

By changing only two locations in the file name decode section 
of DOS, many more characters are permitted. We will modify DOS to 

105 



APPENDIX A 



accept any ASCII characters in a file name except character graphics 
and inverse video. Additionally, the filename can start with a number 
(e.g. "D:3-D"). Unfortunately, there is no foolproof way to allow 
imbe^dded spaces such as "D:TIME OUT". 

The following fragment of code checks to see that a character of 
the file name falls in the range of A-Z. If the character is less than 
(cany clear) 65 [ASC("A")] or greater than or equal to (carry set) 91 
[ASCC'Z") + 1], then the test fails. All we do is change the check for 
"A" to a check for "!" (its number in the code is one greater than 
"space"), and the check for "Z" + 1 to "z" + 1 (lowercase z). 

Included in this range of 90 characters are the numbers (48-57) 
and all punctuation. Since we start with 33, "space" is excluded. It is 
possible to permit imbedded spaces, but the file would then be 
inaccessible in certain situations where a space is used as a delimiter. 
You i:an allow it at your discretion, or even permit the entire (almost) 
AT/iSCII character set to be used by changing the limits to 
and 155. 

CMP #'A 

BCC FD5 

CMP #$5B 

BCC FD6 
We change this to: 

CMP #'! 

BCC FD5 

CMP #$7B 

BCC FD6 

The changes can be made in BASIC with POKE 38 18, 33: POKE 
3822, 123 or change hex locations $OEEA to $21 and $OEEE to $7B. 
The section of code we're modifying is located between source line 
numbers 4072 through 4193. Remember to rewrite the modified DOS 
to disk with WRITE DOS FILES (Menu selection "H") if you want 
your change to be permanent. 

Other equally simple changes are also possible. You could change 
the wild-card character ("*") to any other character by changing 
location $0EC7 to the desired character. A more ambitious task 
would be to increase the maximum file name length. 

This brings up a final point - software compatibility. For example, 
if you changed the wild card character to "@," you couldn't run any 
previ.3us programs that assume "*" as the wild card character. Our 
change is less dangerous - if you allow lowercase file names, the 
unmodified DOS won't be able to access it, although it will look fine 
on the directory. This change has not been exhaustively tested for 

106 



APPENDIX A 



conflicts, so we can't guarantee its usage. Nevertheless, it seems quite 
useful and shows that some customizing can be accomplished with a 
few simple changes. 

When experimenting, always keep a backup copy of your valuable 
disks in case something should go awry. 

100 REM CHANGE DOS PROGRAM 

110 REM FOR DOS 2.0S ONLY 

120 REM CHANGE LOW RANGE CHECK FROM 

130 REM 65 TO 33. THIS ALLOWS 

140 REM ANY CHARACTER (EXCEPT 

150 REM GRAPHICS AND INVERSE VIDEO) 

160 REM TO START A FILENAME, INSTEAD 

170 REM OF ONLY A THROUGH Z. 

180 REM 0EE9 C941 CMP #'A 

190 REM 0EE9 C921 CMP #'! 

200 POKE 3818,33 

210 REM CHANGE HIGH RANGE TO EXTEND 

220 REM UP TO ASCII "z" 

230 REM (LOWERCASE Z) 

240 REM 0EED C95B CMP #$5B 

250 REM 0EED C97B CMP #$7B 

260 REM POKE 3822,123 

270 REM NO NEED TO CHANGE NUMERIC 

280 REM CHECK SINCE IT IS NO 

290 REM LONGER EXECUTED, THANKS 

300 REM TO THE ABOVE CODE. 

Siome Cautions 

C^^are is necessary when making customizations. Only make the changes 
to a copy of your EXDS - not the original "system master." (You 
shouldn't be able to do this anyway, since the disk is "write-protected, " 
but better safe than sorry. ) Remember that any files SAVEd with your 
custom EXDS will probably not be compatible with the original, 
unchanged DOS. Alternation of the DOS can have unpredictable 
effects; we urge caution and cannot accept any liability for software or 
hardware damage incurred through the use of this book. 

Things To Looi( Out For 

These modifications could make a customized DOS incompatible with 
the original, unmodified DOS 2. OS: 

1) File name changes (such as allowing lowercase, or increasing 

107 



APPENDIX A 



the length) 

2) Changes to DOS file stnicture (such as using a different 
"linking" system) 

3) Removing error-checks. These built-in traps insure disk 
integrity and reliability. When you alter one, you could risk 
muddling one or more files. For example, if you allow an automatic 
"wild-card" feature, where an asterisk is assumed at the end of a 
file, it could cause havoc when performing a SCRATCH, 
RENAME, or UPDATE operation. Another example is removing 
some of the qualifications for "burst- I/O." Remember that a lot 
of thought went into each design consideration. 

Keeping these suggestions in mind, here are some ideas for 
modifications. You may need to type in and re-assemble (with your 
insertions) the entire DOS when making certain modifications. 

1 ) Adding a STATUS check before a disk access. Have you ever 
noticed how long the drive will grind away when no disk is 
inserted? You can query the disk for its status, and even add a 
"Drive not ready" error message if the drive door is not closed or 
a disk is not inserted. Check your DOS manual for details. 

2) Adding Disk Utility commands. These would be additional 
functions performed by the FMS, keyed to the "special command. " 
Some of the tasks performed by the Disk Utility Package could be 
a part of the DOS kemal, such as LOAD and SAVE binary files. 
You could even implement new commands such as "relative file" 
support, where you only give the DOS a "record number" to 
randomly access a file. The file could be divided into records of 
any length. 

3) Allocate more sectors for the directory, thereby extending 
the maximum amount of directory entries. 

4) Add a disk name and/or disk I.D. number (serial number?) to 
the disk (maybe on sector 720). It could even print out with the 
directory. 

5) Given the extra "unused" bytes in the file name, add a byte 
for file type, such as program, data, object code, etc. , and have it 
printed out with the directory, making it easy to identify files 
without having to use the extension. This would be hard to 
interface with software, however. 

Remember that some of this is risky business. Keep backup disks 
for any disk you are "experimenting" with. That way, you should lose 
no important files. 

The publishers and authors of this book disclaim any responsibility for errors or 
problems caused by modification of Atari DOS 2. OS. 

108 



NOTES 



109 



NOTES 



110 



NOTES 



111 



NOTES 



112 



NOTES 



113 



NOTES 



114 



NOTES 



115 



NOTES 



116 



COMPUTE! Books 

P.O. Box 5406 Greensboro, NC 27403 

Ask your retailer for these COMPUTE! Books. If he or she 
has sold out, order directly from COMPUTE! 

For Fastest Service 
Call Our TOLL FREE US Order Line 

800-334-0868 

In NC call 919-275-9809 

Quantity Title Price Total 

The Beginner's Guide To 

Buying A Personal Computer $ 3.95 



(Add $1.00 shipping and handling. Outside US add 
S4.00 air mail: $2.00 surface mail.) 

COMPUTEI's First Boole Of Atari $12.95 

(Add $2.00 shipping and handling. Outside US add 
$4.00 air mail; $2.00 surface mail.) 

Inside Atari DOS $19.95 

(Add S2.00 shipping and handling. Outside US add 
$4,00 air mail; $2.00 surface mail.) 

COMPUTERS First Book Of 

PET/CBM $12.95 

(Add $2.00 shipping and handling. Outside US add 
S4.00 air mail; $2.00 surface moil.) 

Programming ttie PET/CBM $24.95 

[Add S3.00 shipping and handling. Outside US odd 
$9,00 air moil; $3.00 surface moil.) 

Every Kid's First Boole of 

Robots and Computers $ 4.95 

(Add $1.00 shipping and handling. Outside US odd 
$4.00 air moil; $2.00 surface mail.) 

COMPUTEI's Second Book Of 

Atari $12.95 

[Add S2.00 shipping and handling. Outside US odd 
$4.00 air mail: $2.00 surface moil.) 

COMPUTEI's First Book of VIC $12.95 

(Add $2.00 shipping and handling. Outside US add 
S4.00 oir mail; $2.00 surface mail.) 

All orders must be prepaid (nnoney order, check, or charge). All 
payments must be in US funds. NC residents add 4% sales tax. 

□ Payment enclosed Please charge my: □ VISA □ MasterCard 

□ American Express Acct No. Expires / 

Name 

Address 

City State Zip 

Country 

Allow 4-5 weel<s for delivery 

02 7 



^ 



f you've enjoyed the articles in this book, you'll find the 
some style and quality in every monthly issue of COMPUTE! 
Magazine. Use this form to order your subscription to 
COMPUTE! 



For Fastest Service, 
Call Our Toil-Free US Order Line 

800-334-0868 

In NO call 919-275-9809 



COMPUTE! 

P.O. Box 5406 
Greensboro, NC 27403 

My Computer Is: 

DPET DApple DAtari DVICDOther D Don't yet have one... 

D $20.00 One Year US Subscription 
n $36.00 Two Year US Subscription 
D $54.00 Three Year US Subscription 

Subscription rotes outside the US: 

D $25.00 Canada f=2 

D $38.00 Europe/Air Delivery fi = 3 

D $48.00 Middle East, North Africa, Central America/Air Mail fi = 5 

n $88.00 South America, South Africa, Australasia/Air Mail fi = 7 

n $25.00 International Surface Mail (lengthy, unreliable delivery] Fi=4,6,a 

Name 

Address 

City State Zip 

Country 

Payment must be in US Funds drav\/n on a US Bank International Money 

Order, or charge card. 

n Payment Enclosed D VISA 

□ MasterCard □ American Express 

Acc't. No. Expires / 

02-7 



-J 



J 



■u 



u 



J 





\\ 



} 



^-\ 



-^